Single cell seq after sorting for PhenoID

sample1 = Neurons1 sample2 = Neurons2 sample3 = Glia1 - Astrocytes (CD44+) sample4 = Glia2 - Radial Glia (CD44-)

In HPC I have run steps of scrnabox (custom pipeline in progress) 1. Cell Ranger for feature seq 2. Create Seurat Objects 3. Apply minimum filtering and calculate percent mitochondria.

I have technical 3 replicates with hashtag labels at this point I haven’t yet demultiplex the hashtags. The data here will be treated as one sample. I sorted three separate samples and pooled them together.

# set up the environment

library(Seurat)
Attaching SeuratObject
Attaching sp
library(dplyr)

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(Matrix)
library(ggplot2)

#rm(list = ls())

Read in the seurat objects made in compute canada

Glia2
An object of class Seurat 
33541 features across 10338 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO

Have a look at the objects that already have some filtering

See the violin plots


VlnPlot(Neurons1, pt.size = 0.10, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)


VlnPlot(Neurons1, pt.size = 0.10, features = c("nFeature_RNA"), y.max = 500)
Warning: Removed 873 rows containing non-finite values (stat_ydensity).
Warning: Removed 873 rows containing missing values (geom_point).

VlnPlot(Neurons1, pt.size = 0.10, features = c("nCount_RNA"), y.max = 2000)
Warning: Removed 546 rows containing non-finite values (stat_ydensity).
Warning: Removed 546 rows containing missing values (geom_point).

# filter more cells

Neuron1.ft <- subset(Neurons1, subset = nFeature_RNA > 250 & nCount_RNA > 250 & nCount_RNA < 10000) 
Neuron1.ft
An object of class Seurat 
33541 features across 1833 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO
# 33541 features across 1833 samples

Neurons 2 - CD56++


VlnPlot(Neurons2, pt.size = 0.10, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)

VlnPlot(Neurons2, pt.size = 0.10, features = c("nFeature_RNA"), y.max = 500)
Warning: Removed 5653 rows containing non-finite values (stat_ydensity).
Warning: Removed 5653 rows containing missing values (geom_point).

VlnPlot(Neurons2, pt.size = 0.10, features = c("nFeature_RNA"), y.max = 1000)
Warning: Removed 2379 rows containing non-finite values (stat_ydensity).
Warning: Removed 2379 rows containing missing values (geom_point).

VlnPlot(Neurons2, pt.size = 0.10, features = c("nCount_RNA"), y.max = 2000)
Warning: Removed 2264 rows containing non-finite values (stat_ydensity).
Warning: Removed 2264 rows containing missing values (geom_point).

# filter more cells

Neuron2.ft <- subset(Neurons2, subset = nFeature_RNA > 500 & nCount_RNA > 500 & nCount_RNA < 10000) 
Neuron2.ft
An object of class Seurat 
33541 features across 5190 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO

Glia1 - Astrocyte data


VlnPlot(Glia1, pt.size = 0.10, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)


VlnPlot(Glia1, pt.size = 0.10, features = c("nFeature_RNA"), y.max = 5000)
Warning: Removed 82 rows containing non-finite values (stat_ydensity).
Warning: Removed 82 rows containing missing values (geom_point).

VlnPlot(Glia1, pt.size = 0.10, features = c("nFeature_RNA"), y.max = 1000)
Warning: Removed 11811 rows containing non-finite values (stat_ydensity).
Warning: Removed 11811 rows containing missing values (geom_point).

VlnPlot(Glia1, pt.size = 0.10, features = c("nCount_RNA"), y.max = 1000)
Warning: Removed 25751 rows containing non-finite values (stat_ydensity).
Warning: Removed 25751 rows containing missing values (geom_point).

VlnPlot(Glia1, pt.size = 0.10, features = c("nCount_RNA"), y.max = 12000)
Warning: Removed 252 rows containing non-finite values (stat_ydensity).
Warning: Removed 252 rows containing missing values (geom_point).

# extreme filter

Glia1.ft <- subset(Glia1, subset = nFeature_RNA > 500 & nCount_RNA > 300 & nCount_RNA < 10000) 
Glia1.ft
An object of class Seurat 
33541 features across 37813 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO
Glia1
An object of class Seurat 
33541 features across 54723 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO
VlnPlot(Glia1.ft, pt.size = 0.10, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)

NA
NA
NA
NA
NA

Glia2 - Radial Glia


## Filter Glia 2
VlnPlot(Glia2, pt.size = 0.10, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)


VlnPlot(Glia2, pt.size = 0.10, features = c("nFeature_RNA"), y.max = 5000)
Warning: Removed 61 rows containing non-finite values (stat_ydensity).
Warning: Removed 61 rows containing missing values (geom_point).

VlnPlot(Glia2, pt.size = 0.10, features = c("nFeature_RNA"), y.max = 1000)
Warning: Removed 2435 rows containing non-finite values (stat_ydensity).
Warning: Removed 2435 rows containing missing values (geom_point).

VlnPlot(Glia2, pt.size = 0.10, features = c("nCount_RNA"), y.max = 1000)
Warning: Removed 3194 rows containing non-finite values (stat_ydensity).
Warning: Removed 3194 rows containing missing values (geom_point).

VlnPlot(Glia2, pt.size = 0.10, features = c("nCount_RNA"), y.max = 12000)
Warning: Removed 199 rows containing non-finite values (stat_ydensity).
Warning: Removed 199 rows containing missing values (geom_point).

# extreme filter

Glia2.ft <- subset(Glia1, subset = nFeature_RNA > 500 & nCount_RNA > 500 & nCount_RNA < 10000) 
Glia2.ft
An object of class Seurat 
33541 features across 37813 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO
VlnPlot(Glia1.ft, pt.size = 0.10, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)


# there are so many suposed cells I am concerned the high read cells are actually doublets. 

Analyze each dataset - get clusters


# cluster the neurons
seu <- Neuron1.ft
seu$orig.ident <- 'Neurons1'

seu <- NormalizeData(seu, normalization.method = "LogNormalize", scale.factor = 10000)
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
seu <- FindVariableFeatures(seu, selection.method = "vst", nfeatures = 2000)
Calculating gene variances
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating feature variances of standardized and clipped values
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
# Identify the 10 most highly variable genes
top10 <- head(VariableFeatures(seu), 10)
# plot variable features with and without labels
plot1 <- VariableFeaturePlot(seu)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
When using repel, set xnudge and ynudge to 0 for optimal results
seu <- ScaleData(seu)
Centering and scaling data matrix

  |                                                                                                      
  |                                                                                                |   0%
  |                                                                                                      
  |================================================                                                |  50%
  |                                                                                                      
  |================================================================================================| 100%
seu <- RunPCA(seu)
PC_ 1 
Positive:  CDH19, MPZ, COL4A1, COL4A2, COL3A1, ZEB2, CTSC, OLFML2A, MIA, FN1 
       NRXN1, ERBB3, TGFBR2, COL14A1, COL1A2, FST, COL5A2, COL28A1, PLAT, SHC4 
       NTM, PMEPA1, KCTD12, CAVIN3, SOX10, LAMC1, BGN, IFI16, LIMCH1, GAS2L3 
Negative:  CLU, PTGDS, DLK1, SPARCL1, PTN, APOE, SAT1, TFPI2, GDF10, HPD 
       TMSB4X, C1orf61, MGST1, TRH, NRIP3, RBP4, WIF1, NUPR1, IGFBP7, LIX1 
       FGFBP1, ESM1, TPPP3, GNG11, BAALC-AS2, BAALC, LY6H, WNT2B, SFRP2, CRYAB 
PC_ 2 
Positive:  CELF4, ANK3, CACNA2D1, PCDH9, NCKAP5, CHGB, SYT1, NEUROD1, PCLO, GNB3 
       OTX2, STMN2, PTPRR, INA, OCIAD2, IMPG2, DCX, DYNC1I1, SSTR2, ZFHX4 
       BTBD8, STMN1, GRIA2, MARCH1, SLC1A2, ATP1A3, STMN4, AMER2, BEX1, FAM19A4 
Negative:  CDH19, COL3A1, MPZ, CTSC, OLFML2A, COL4A2, COL4A1, MIA, VIM, FN1 
       TGFBR2, COL1A2, ERBB3, ZEB2, S100B, SPARC, COL14A1, S100A10, IFITM3, COL5A2 
       CAVIN3, PLAT, COL28A1, SOX10, FST, PLEKHA4, GAS2L3, CXCL12, ITIH5, LGALS1 
PC_ 3 
Positive:  PCAT4, IMPG2, NEUROD1, NRXN1, CDH19, PLPPR4, TPH1, SYT1, ZEB2, MPZ 
       MIA, GSG1, STMN2, OLFML2A, SST, OLFM3, FAM19A4, CTSC, GNB3, PTPRR 
       BTBD8, COL3A1, GAS2L3, BCAT1, SOX10, COL4A2, ERBB3, CHGB, SORCS1, COL28A1 
Negative:  TPBG, SLC7A8, WLS, FSTL1, HES1, ANO10, PAPPA2, CDH2, MSX1, SLC2A1 
       ZFP36L1, PIP5K1B, NFIA, TSC22D1, SLCO1C1, SOX2, PRNP, LINC00473, SPRY1, WIF1 
       NOV, COLEC12, PLCG2, GDF10, SPATS2L, RRBP1, BMP7, PAG1, WFIKKN2, RFX4 
PC_ 4 
Positive:  EOMES, MGAT4C, ELAVL3, LHX1, RASGRP1, ADCYAP1, ELAVL4, SLC16A12, CELF4, TSHZ2 
       PTPRO, KCNK1, SCN9A, RELN, EPS8, RAB3B, SLIT1, GRID2, ASCL1, KRT222 
       ZNF385D, DCLK1, BDNF, ELAVL2, RGMB, PLCXD3, UNC5D, RALYL, PPP1R14C, DNER 
Negative:  PCAT4, TPH1, IMPG2, BCAT1, SST, FAM19A4, BTBD8, ETV3L, GSG1, PLPPR4 
       IL15, GABRG2, PDE6H, OLFM3, GNB3, CLSTN2, CRABP2, RBFOX1, AC007349.2, LINC02208 
       AIPL1, RD3, KCNH5, NCKAP5, PRKG2, AANAT, LRRC39, ANO2, ISOC1, AP000459.1 
PC_ 5 
Positive:  PTN, PTPRZ1, SPARCL1, MEGF10, ESM1, DLK1, GABBR2, ATP1A2, NRIP3, GDF10 
       NELL2, SOX2, CBLN1, APCDD1, SYTL4, SERPINI1, ARHGAP26, PTGDS, VIPR2, FTL 
       MARCKS, GNG11, TRH, IL17RD, EPHB1, RBP4, RSPO2, APOE, OGFRL1, AKR1C1 
Negative:  CYP1B1, CP, ECEL1, CXCL14, IGFBP3, WIF1, WFIKKN2, MALAT1, FHIT, EPAS1 
       SLC4A10, EMX2, PAPPA2, TRPM3, EFEMP1, BMP4, MGP, KCNJ13, ID1, EXPH5 
       KRT18, KRT8, FBLN1, MSX1, FOS, GPNMB, DCN, CDC42EP3, COL6A3, SERPINF1 
Idents(seu) <- 'orig.ident'
plot <- DimPlot(seu, reduction = "pca")


plot3 <- ElbowPlot(seu,ndims = 50)
plot3


plot2
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Removed 13701 rows containing missing values (geom_point).

plot

NA
NA
NA

# umap

seu <- RunUMAP(seu, reduction = "pca", n.neighbors = 43, dims = 1:25)
Warning: The default method for RunUMAP has changed from calling Python UMAP via reticulate to the R-native UWOT using the cosine metric
To use Python UMAP via reticulate, set umap.method to 'umap-learn' and metric to 'correlation'
This message will be shown once per session
08:59:48 UMAP embedding parameters a = 0.9922 b = 1.112
08:59:48 Read 1833 rows and found 25 numeric columns
08:59:48 Using Annoy for neighbor search, n_neighbors = 43
08:59:48 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
08:59:48 Writing NN index file to temp file /var/folders/k4/khtkczkd5tn732ftjpwgtr240000gn/T//RtmpioYRC5/file1726b7ea878e1
08:59:48 Searching Annoy index using 1 thread, search_k = 4300
08:59:48 Annoy recall = 100%
08:59:49 Commencing smooth kNN distance calibration using 1 thread with target n_neighbors = 43
08:59:49 Initializing from normalized Laplacian + noise (using irlba)
08:59:49 Commencing optimization for 500 epochs, with 107418 positive edges
Using method 'umap'
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
08:59:53 Optimization finished
DimPlot(seu, reduction = "umap", group.by = "orig.ident")

NA
NA
NA

Make the clusters Neurons1


seu <- FindNeighbors(seu, dims = 1:25, k.param = 43)
Computing nearest neighbor graph
Computing SNN
seu <- FindClusters(seu, resolution = c(0,0.2,0.25,0.5,0.8))
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1833
Number of edges: 146997

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 1.0000
Number of communities: 1
Elapsed time: 0 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1833
Number of edges: 146997

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8606
Number of communities: 4
Elapsed time: 0 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1833
Number of edges: 146997

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8446
Number of communities: 5
Elapsed time: 0 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1833
Number of edges: 146997

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7787
Number of communities: 6
Elapsed time: 0 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1833
Number of edges: 146997

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7092
Number of communities: 8
Elapsed time: 0 seconds
seu <- FindClusters(seu, resolution = c(1.2))
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1833
Number of edges: 146997

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.6403
Number of communities: 10
Elapsed time: 0 seconds
library(clustree)
Loading required package: ggraph

Attaching package: ‘ggraph’

The following object is masked from ‘package:sp’:

    geometry
clustree(seu, prefix = "RNA_snn_res.")

DimPlot(seu)

# look a lot at the clusers

VlnPlot(seu, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), group.by = 'seurat_clusters', ncol = 1)

# these cells might be grouping by - how much MT and number of Features
# clusters 4,5,6 have more features

VlnPlot(seu, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), group.by = 'RNA_snn_res.0.25', ncol = 1)

# here cluster 3 has higher expression, cluster 1 and 4 have similar Features RNA
# cluster 0 has higher percent MT levels

VlnPlot(seu, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), group.by = 'RNA_snn_res.0.5', ncol = 1)

VlnPlot(seu, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), group.by = 'RNA_snn_res.0.2', ncol = 1)

# now only cluster 0 have high MT and low features, clusters 1,2,3 have simiular RNA and Counts

Find the cluster markers for Neurons1

Idents(seu) <- 'RNA_snn_res.0.2'
ClusterMarkers <- FindAllMarkers(seu)
Calculating cluster 0

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~10s          
  |++                                                | 2 % ~09s          
  |++                                                | 3 % ~09s          
  |+++                                               | 4 % ~09s          
  |+++                                               | 5 % ~09s          
  |++++                                              | 6 % ~09s          
  |++++                                              | 7 % ~09s          
  |+++++                                             | 8 % ~08s          
  |+++++                                             | 9 % ~08s          
  |++++++                                            | 10% ~09s          
  |++++++                                            | 11% ~08s          
  |+++++++                                           | 12% ~08s          
  |+++++++                                           | 13% ~08s          
  |++++++++                                          | 14% ~08s          
  |++++++++                                          | 15% ~08s          
  |+++++++++                                         | 16% ~08s          
  |+++++++++                                         | 17% ~08s          
  |++++++++++                                        | 18% ~08s          
  |++++++++++                                        | 19% ~07s          
  |+++++++++++                                       | 20% ~07s          
  |+++++++++++                                       | 21% ~07s          
  |++++++++++++                                      | 22% ~07s          
  |++++++++++++                                      | 23% ~07s          
  |+++++++++++++                                     | 24% ~07s          
  |+++++++++++++                                     | 26% ~07s          
  |++++++++++++++                                    | 27% ~07s          
  |++++++++++++++                                    | 28% ~07s          
  |+++++++++++++++                                   | 29% ~07s          
  |+++++++++++++++                                   | 30% ~06s          
  |++++++++++++++++                                  | 31% ~06s          
  |++++++++++++++++                                  | 32% ~06s          
  |+++++++++++++++++                                 | 33% ~06s          
  |+++++++++++++++++                                 | 34% ~06s          
  |++++++++++++++++++                                | 35% ~06s          
  |++++++++++++++++++                                | 36% ~06s          
  |+++++++++++++++++++                               | 37% ~06s          
  |+++++++++++++++++++                               | 38% ~06s          
  |++++++++++++++++++++                              | 39% ~06s          
  |++++++++++++++++++++                              | 40% ~05s          
  |+++++++++++++++++++++                             | 41% ~05s          
  |+++++++++++++++++++++                             | 42% ~05s          
  |++++++++++++++++++++++                            | 43% ~05s          
  |++++++++++++++++++++++                            | 44% ~05s          
  |+++++++++++++++++++++++                           | 45% ~05s          
  |+++++++++++++++++++++++                           | 46% ~05s          
  |++++++++++++++++++++++++                          | 47% ~05s          
  |++++++++++++++++++++++++                          | 48% ~05s          
  |+++++++++++++++++++++++++                         | 49% ~05s          
  |+++++++++++++++++++++++++                         | 50% ~05s          
  |++++++++++++++++++++++++++                        | 51% ~04s          
  |+++++++++++++++++++++++++++                       | 52% ~04s          
  |+++++++++++++++++++++++++++                       | 53% ~04s          
  |++++++++++++++++++++++++++++                      | 54% ~04s          
  |++++++++++++++++++++++++++++                      | 55% ~04s          
  |+++++++++++++++++++++++++++++                     | 56% ~04s          
  |+++++++++++++++++++++++++++++                     | 57% ~04s          
  |++++++++++++++++++++++++++++++                    | 58% ~04s          
  |++++++++++++++++++++++++++++++                    | 59% ~04s          
  |+++++++++++++++++++++++++++++++                   | 60% ~04s          
  |+++++++++++++++++++++++++++++++                   | 61% ~04s          
  |++++++++++++++++++++++++++++++++                  | 62% ~03s          
  |++++++++++++++++++++++++++++++++                  | 63% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 64% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~03s          
  |++++++++++++++++++++++++++++++++++                | 66% ~03s          
  |++++++++++++++++++++++++++++++++++                | 67% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~03s          
  |++++++++++++++++++++++++++++++++++++              | 70% ~03s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~03s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 78% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 82% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=09s  
Calculating cluster 1

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~08s          
  |++                                                | 2 % ~08s          
  |++                                                | 3 % ~08s          
  |+++                                               | 4 % ~08s          
  |+++                                               | 5 % ~07s          
  |++++                                              | 6 % ~07s          
  |++++                                              | 7 % ~07s          
  |+++++                                             | 8 % ~07s          
  |+++++                                             | 9 % ~07s          
  |++++++                                            | 10% ~07s          
  |++++++                                            | 11% ~07s          
  |+++++++                                           | 12% ~07s          
  |+++++++                                           | 13% ~07s          
  |++++++++                                          | 14% ~07s          
  |++++++++                                          | 15% ~07s          
  |+++++++++                                         | 16% ~06s          
  |+++++++++                                         | 18% ~06s          
  |++++++++++                                        | 19% ~06s          
  |++++++++++                                        | 20% ~06s          
  |+++++++++++                                       | 21% ~06s          
  |+++++++++++                                       | 22% ~06s          
  |++++++++++++                                      | 23% ~06s          
  |++++++++++++                                      | 24% ~06s          
  |+++++++++++++                                     | 25% ~06s          
  |+++++++++++++                                     | 26% ~06s          
  |++++++++++++++                                    | 27% ~06s          
  |++++++++++++++                                    | 28% ~06s          
  |+++++++++++++++                                   | 29% ~05s          
  |+++++++++++++++                                   | 30% ~05s          
  |++++++++++++++++                                  | 31% ~05s          
  |++++++++++++++++                                  | 32% ~05s          
  |+++++++++++++++++                                 | 33% ~05s          
  |++++++++++++++++++                                | 34% ~05s          
  |++++++++++++++++++                                | 35% ~05s          
  |+++++++++++++++++++                               | 36% ~05s          
  |+++++++++++++++++++                               | 37% ~05s          
  |++++++++++++++++++++                              | 38% ~05s          
  |++++++++++++++++++++                              | 39% ~05s          
  |+++++++++++++++++++++                             | 40% ~05s          
  |+++++++++++++++++++++                             | 41% ~05s          
  |++++++++++++++++++++++                            | 42% ~04s          
  |++++++++++++++++++++++                            | 43% ~04s          
  |+++++++++++++++++++++++                           | 44% ~04s          
  |+++++++++++++++++++++++                           | 45% ~04s          
  |++++++++++++++++++++++++                          | 46% ~04s          
  |++++++++++++++++++++++++                          | 47% ~04s          
  |+++++++++++++++++++++++++                         | 48% ~04s          
  |+++++++++++++++++++++++++                         | 49% ~04s          
  |++++++++++++++++++++++++++                        | 51% ~04s          
  |++++++++++++++++++++++++++                        | 52% ~04s          
  |+++++++++++++++++++++++++++                       | 53% ~04s          
  |+++++++++++++++++++++++++++                       | 54% ~04s          
  |++++++++++++++++++++++++++++                      | 55% ~04s          
  |++++++++++++++++++++++++++++                      | 56% ~03s          
  |+++++++++++++++++++++++++++++                     | 57% ~03s          
  |+++++++++++++++++++++++++++++                     | 58% ~03s          
  |++++++++++++++++++++++++++++++                    | 59% ~03s          
  |++++++++++++++++++++++++++++++                    | 60% ~03s          
  |+++++++++++++++++++++++++++++++                   | 61% ~03s          
  |+++++++++++++++++++++++++++++++                   | 62% ~03s          
  |++++++++++++++++++++++++++++++++                  | 63% ~03s          
  |++++++++++++++++++++++++++++++++                  | 64% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~03s          
  |++++++++++++++++++++++++++++++++++                | 67% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~02s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~02s          
  |++++++++++++++++++++++++++++++++++++              | 70% ~02s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 76% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 78% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 80% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 82% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=08s  
Calculating cluster 2

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~06s          
  |++                                                | 2 % ~06s          
  |++                                                | 3 % ~05s          
  |+++                                               | 4 % ~05s          
  |+++                                               | 5 % ~05s          
  |++++                                              | 6 % ~05s          
  |++++                                              | 8 % ~05s          
  |+++++                                             | 9 % ~05s          
  |+++++                                             | 10% ~05s          
  |++++++                                            | 11% ~05s          
  |++++++                                            | 12% ~05s          
  |+++++++                                           | 13% ~05s          
  |+++++++                                           | 14% ~05s          
  |++++++++                                          | 15% ~05s          
  |+++++++++                                         | 16% ~05s          
  |+++++++++                                         | 17% ~04s          
  |++++++++++                                        | 18% ~04s          
  |++++++++++                                        | 19% ~04s          
  |+++++++++++                                       | 20% ~04s          
  |+++++++++++                                       | 22% ~04s          
  |++++++++++++                                      | 23% ~04s          
  |++++++++++++                                      | 24% ~04s          
  |+++++++++++++                                     | 25% ~04s          
  |+++++++++++++                                     | 26% ~04s          
  |++++++++++++++                                    | 27% ~04s          
  |++++++++++++++                                    | 28% ~04s          
  |+++++++++++++++                                   | 29% ~04s          
  |++++++++++++++++                                  | 30% ~04s          
  |++++++++++++++++                                  | 31% ~04s          
  |+++++++++++++++++                                 | 32% ~04s          
  |+++++++++++++++++                                 | 33% ~04s          
  |++++++++++++++++++                                | 34% ~04s          
  |++++++++++++++++++                                | 35% ~04s          
  |+++++++++++++++++++                               | 37% ~03s          
  |+++++++++++++++++++                               | 38% ~03s          
  |++++++++++++++++++++                              | 39% ~03s          
  |++++++++++++++++++++                              | 40% ~03s          
  |+++++++++++++++++++++                             | 41% ~03s          
  |+++++++++++++++++++++                             | 42% ~03s          
  |++++++++++++++++++++++                            | 43% ~03s          
  |+++++++++++++++++++++++                           | 44% ~03s          
  |+++++++++++++++++++++++                           | 45% ~03s          
  |++++++++++++++++++++++++                          | 46% ~03s          
  |++++++++++++++++++++++++                          | 47% ~03s          
  |+++++++++++++++++++++++++                         | 48% ~03s          
  |+++++++++++++++++++++++++                         | 49% ~03s          
  |++++++++++++++++++++++++++                        | 51% ~03s          
  |++++++++++++++++++++++++++                        | 52% ~03s          
  |+++++++++++++++++++++++++++                       | 53% ~03s          
  |+++++++++++++++++++++++++++                       | 54% ~03s          
  |++++++++++++++++++++++++++++                      | 55% ~02s          
  |++++++++++++++++++++++++++++                      | 56% ~02s          
  |+++++++++++++++++++++++++++++                     | 57% ~02s          
  |++++++++++++++++++++++++++++++                    | 58% ~02s          
  |++++++++++++++++++++++++++++++                    | 59% ~02s          
  |+++++++++++++++++++++++++++++++                   | 60% ~02s          
  |+++++++++++++++++++++++++++++++                   | 61% ~02s          
  |++++++++++++++++++++++++++++++++                  | 62% ~02s          
  |++++++++++++++++++++++++++++++++                  | 63% ~02s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~02s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~02s          
  |++++++++++++++++++++++++++++++++++                | 67% ~02s          
  |++++++++++++++++++++++++++++++++++                | 68% ~02s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~02s          
  |+++++++++++++++++++++++++++++++++++               | 70% ~02s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~01s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~01s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~01s          
  |+++++++++++++++++++++++++++++++++++++++           | 76% ~01s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~01s          
  |++++++++++++++++++++++++++++++++++++++++          | 78% ~01s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++         | 82% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=06s  
Calculating cluster 3

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~09s          
  |++                                                | 2 % ~09s          
  |++                                                | 3 % ~09s          
  |+++                                               | 4 % ~09s          
  |+++                                               | 5 % ~09s          
  |++++                                              | 6 % ~09s          
  |++++                                              | 7 % ~08s          
  |+++++                                             | 8 % ~08s          
  |+++++                                             | 9 % ~09s          
  |++++++                                            | 10% ~09s          
  |++++++                                            | 11% ~08s          
  |+++++++                                           | 12% ~08s          
  |+++++++                                           | 13% ~08s          
  |++++++++                                          | 14% ~08s          
  |++++++++                                          | 15% ~08s          
  |+++++++++                                         | 16% ~08s          
  |+++++++++                                         | 18% ~08s          
  |++++++++++                                        | 19% ~07s          
  |++++++++++                                        | 20% ~07s          
  |+++++++++++                                       | 21% ~07s          
  |+++++++++++                                       | 22% ~07s          
  |++++++++++++                                      | 23% ~07s          
  |++++++++++++                                      | 24% ~07s          
  |+++++++++++++                                     | 25% ~07s          
  |+++++++++++++                                     | 26% ~07s          
  |++++++++++++++                                    | 27% ~07s          
  |++++++++++++++                                    | 28% ~06s          
  |+++++++++++++++                                   | 29% ~06s          
  |+++++++++++++++                                   | 30% ~06s          
  |++++++++++++++++                                  | 31% ~06s          
  |++++++++++++++++                                  | 32% ~06s          
  |+++++++++++++++++                                 | 33% ~06s          
  |++++++++++++++++++                                | 34% ~06s          
  |++++++++++++++++++                                | 35% ~06s          
  |+++++++++++++++++++                               | 36% ~06s          
  |+++++++++++++++++++                               | 37% ~06s          
  |++++++++++++++++++++                              | 38% ~06s          
  |++++++++++++++++++++                              | 39% ~05s          
  |+++++++++++++++++++++                             | 40% ~05s          
  |+++++++++++++++++++++                             | 41% ~05s          
  |++++++++++++++++++++++                            | 42% ~05s          
  |++++++++++++++++++++++                            | 43% ~05s          
  |+++++++++++++++++++++++                           | 44% ~05s          
  |+++++++++++++++++++++++                           | 45% ~05s          
  |++++++++++++++++++++++++                          | 46% ~05s          
  |++++++++++++++++++++++++                          | 47% ~05s          
  |+++++++++++++++++++++++++                         | 48% ~05s          
  |+++++++++++++++++++++++++                         | 49% ~04s          
  |++++++++++++++++++++++++++                        | 51% ~04s          
  |++++++++++++++++++++++++++                        | 52% ~04s          
  |+++++++++++++++++++++++++++                       | 53% ~04s          
  |+++++++++++++++++++++++++++                       | 54% ~04s          
  |++++++++++++++++++++++++++++                      | 55% ~04s          
  |++++++++++++++++++++++++++++                      | 56% ~04s          
  |+++++++++++++++++++++++++++++                     | 57% ~04s          
  |+++++++++++++++++++++++++++++                     | 58% ~04s          
  |++++++++++++++++++++++++++++++                    | 59% ~04s          
  |++++++++++++++++++++++++++++++                    | 60% ~04s          
  |+++++++++++++++++++++++++++++++                   | 61% ~03s          
  |+++++++++++++++++++++++++++++++                   | 62% ~03s          
  |++++++++++++++++++++++++++++++++                  | 63% ~03s          
  |++++++++++++++++++++++++++++++++                  | 64% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~03s          
  |++++++++++++++++++++++++++++++++++                | 67% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~03s          
  |++++++++++++++++++++++++++++++++++++              | 70% ~03s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~03s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 76% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 78% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 80% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 82% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=09s  
top5 <- ClusterMarkers %>% group_by(cluster) %>% top_n(n=5, wt = avg_log2FC)
DoHeatmap(seu, features = top5$gene, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.2')



#write.csv(ClusterMarkers, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/ClusterMarkers_neurons1_res025.csv")


write.csv(ClusterMarkers, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/ClusterMarkers_neurons1_res02.csv")
DimPlot(seu, group.by = 'RNA_snn_res.0.2', reduction = 'umap')

Get the most highly expressed genes in the total data (Neurons1)

Filters out specific genes


seu.ft <- seu[!grepl("MALAT1", rownames(seu)), ]
seu.ft <- seu.ft[!grepl("^MT-", rownames(seu.ft)), ]

Try to find doublets with doublet finder

remotes::install_github('chris-mcginnis-ucsf/DoubletFinder')
Skipping install of 'DoubletFinder' from a github remote, the SHA1 (67fb8b58) has not changed since last install.
  Use `force = TRUE` to force installation
suppressMessages(require(DoubletFinder))

Do the double cells have more genes than the singlet??


VlnPlot(seu.d, features = "nFeature_RNA", group.by = DF.name, pt.size = 0.1)

NA
NA

remove the doublets

dim(seu.d)
[1] 33538  1723
dim(seu)
[1] 33538  1833

Save the filtered, doublet removed Neurons object Re-run PCA for clustering


saveRDS(seu.d, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/objs/NeuronsFilteredSeu28092022.RDS")

DAsubgroups data has not be re-processed Run standard workflow chunk

seu <- AIW60
seu <- NormalizeData(seu, normalization.method = "LogNormalize", scale.factor = 10000)
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
seu <- FindVariableFeatures(seu, selection.method = "vst", nfeatures = 2000)
Calculating gene variances
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating feature variances of standardized and clipped values
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
seu <- ScaleData(seu)
Centering and scaling data matrix

  |                                                                                                      
  |                                                                                                |   0%
  |                                                                                                      
  |================================================                                                |  50%
  |                                                                                                      
  |================================================================================================| 100%
seu <- RunPCA(seu)
PC_ 1 
Positive:  STMN2, DCX, INA, MAP2, SOX4, KIF5C, NCAM1, GAP43, SOX11, NSG2 
       ANK3, GPM6A, SYT1, TUBB2A, NRXN1, PKIA, NR2F1, STMN4, UCHL1, RTN1 
       TAGLN3, RUNX1T1, DPYSL3, NSG1, NEFM, PGM2L1, PRKAR2B, PBX1, POU2F2, ELAVL4 
Negative:  SPARC, ZFP36L1, VIM, TPBG, MDK, ANXA5, GNG5, CD9, CA2, CAST 
       ANXA2, HES1, FSTL1, NFIA, CD99, IGFBP2, TTR, IGFBP7, GSTP1, ID1 
       ID3, CYSTM1, PLTP, ZFP36L2, TRPM3, FAT1, COLEC12, B2M, SPARCL1, TMEM123 
PC_ 2 
Positive:  TTR, TPBG, IGFBP7, ANXA2, TRPM3, SLC7A8, CD9, SPINT2, CHCHD2, NFIA 
       SPARCL1, COLEC12, PPIC, PRNP, WFIKKN2, PIFO, BMP4, DMKN, LINC01088, ID1 
       MITF, CA2, ECEL1, SLC5A3, SERPINF1, CFAP126, PCP4, KRT18, SELENOP, CPVL 
Negative:  NUSAP1, TOP2A, MKI67, CENPF, PBK, CDK1, TPX2, NUF2, UBE2C, BIRC5 
       MAD2L1, CCNA2, ASPM, NCAPG, SPC25, PCLAF, CENPU, PIMREG, NDC80, KNL1 
       SMC4, KIF15, DLGAP5, SGO1, CDCA2, CDCA8, MIS18BP1, RRM2, CENPE, KIF11 
PC_ 3 
Positive:  TTYH1, PTPRZ1, NES, QKI, VIM, BOC, FGFBP3, HES5, SOX2, SLC1A3 
       RFX4, FAM181B, IGDCC3, FAM181A, EDNRB, LINC00461, PON2, RPS27L, VCAM1, CCND1 
       ARHGEF6, ZFP36L1, PLP1, JAG1, PCDH18, ITGB8, SMOC1, DLK1, TMEM38B, TFDP2 
Negative:  RTN1, STMN2, NSG2, GAP43, INA, PRKAR2B, MAPT, UCHL1, NRXN1, PKIA 
       TRPM3, IGFBP7, NSG1, C11orf88, NCAM1, SHTN1, DLGAP5, PCP4, SOBP, DCX 
       CFAP126, ANK3, TTR, NEK2, HIST1H4C, GPM6A, XPR1, CELF4, SPINT2, MITF 
PC_ 4 
Positive:  C11orf88, CAPSL, C1orf194, FAM81B, AKAP14, FAM183A, CFAP126, C9orf24, RSPH1, TCTEX1D1 
       ROPN1L, PIFO, C5orf49, CFAP52, DAW1, ARMC3, CCDC170, FAM216B, EFCAB1, MAP3K19 
       CP, SPAG6, CFAP45, AL357093.2, TEKT1, ANKRD66, MORN5, PTPRC, DYNLRB2, CFAP299 
Negative:  CNTNAP2, SYT4, ZIC1, APP, ZIC2, CBLN1, TNC, APCDD1, PTN, EPHA7 
       PAX6, SLITRK6, DSP, SPARCL1, WLS, ZFHX4, RSPO2, ATP1A2, CDK6, TXNIP 
       IL17RD, TPBG, AMER2, GDF10, ZIC4, PCDH9, WNT2B, HES1, GAP43, ITGA6 
PC_ 5 
Positive:  CALM1, TMSB4X, C11orf88, CKB, ACAT2, C1orf194, FGFBP3, C5orf49, HMGCS1, NR2F1 
       SCD, PTPRZ1, AKAP14, CAPSL, MSMO1, CFAP126, RPS2, IDI1, FAM81B, FDPS 
       FAM183A, PEG10, RSPH1, FDFT1, TUBA1B, GPM6B, ROPN1L, ARL4A, QKI, NTRK2 
Negative:  CCNB1, PLK1, UBE2C, BUB1, CDC20, ASPM, KIF20A, CENPA, CDCA8, DLGAP5 
       AURKA, KIF2C, CCNB2, NEK2, FAM83D, TTK, NUF2, PIF1, TPX2, KIF14 
       GTSE1, CDCA3, CDKN3, PIMREG, HMMR, CENPE, CDCA2, DEPDC1, CKAP2L, SGO2 
seu <- RunUMAP(seu, reduction = "pca", n.neighbors = 123, dims = 1:30)
Warning: The default method for RunUMAP has changed from calling Python UMAP via reticulate to the R-native UWOT using the cosine metric
To use Python UMAP via reticulate, set umap.method to 'umap-learn' and metric to 'correlation'
This message will be shown once per session
13:03:03 UMAP embedding parameters a = 0.9922 b = 1.112
13:03:03 Read 15339 rows and found 30 numeric columns
13:03:03 Using Annoy for neighbor search, n_neighbors = 123
13:03:03 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
13:03:04 Writing NN index file to temp file /var/folders/k4/khtkczkd5tn732ftjpwgtr240000gn/T//RtmphW80ig/file17bc7524a9002
13:03:04 Searching Annoy index using 1 thread, search_k = 12300
13:03:14 Annoy recall = 100%
13:03:14 Commencing smooth kNN distance calibration using 1 thread with target n_neighbors = 123
13:03:16 Initializing from normalized Laplacian + noise (using irlba)
13:03:17 Commencing optimization for 200 epochs, with 2087112 positive edges
Using method 'umap'
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
13:03:32 Optimization finished
DimPlot(seu, reduction = "umap")

Annotate clusters Use: Organoid data, public brain data (LaManno, Lake, Mascako)

top10 <- head(VariableFeatures(DAsubtypes.sub), 10)
# plot variable features with and without labels
plot1 <- VariableFeaturePlot(DAsubtypes.sub)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
When using repel, set xnudge and ynudge to 0 for optimal results
plot2
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Removed 9387 rows containing missing values (geom_point).

See how each looks on UMAP


DimPlot(seu.q, group.by = 'RNA_snn_res.1.2')

DimPlot(seu.q, group.by = 'RNA_snn_res.0.2')

DimPlot(seu.q, group.by = 'AIW60.pred')

DimPlot(seu.q, group.by = 'MBOAIW.pred')

DimPlot(seu.q, group.by = 'MBOAST23.pred')

NA
NA
FindClusters(seu.q, resolution = c(0, 0.2,0.4,0.6))
Error in FindClusters.Seurat(seu.q, resolution = c(0, 0.2, 0.4, 0.6)) : 
  Provided graph.name not present in Seurat object
NA

Redo find clusters


seu.q <- FindNeighbors(seu.q, dims = 1:25, k.param = 43)
Computing nearest neighbor graph
Computing SNN
seu.q <- FindClusters(seu.q, resolution = c(0,0.2,0.4,0.6))
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1723
Number of edges: 145289

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 1.0000
Number of communities: 1
Elapsed time: 0 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1723
Number of edges: 145289

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8573
Number of communities: 4
Elapsed time: 0 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1723
Number of edges: 145289

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7887
Number of communities: 6
Elapsed time: 0 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1723
Number of edges: 145289

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7394
Number of communities: 7
Elapsed time: 0 seconds
seu.q <- FindClusters(seu.q, resolution = c(1.2))
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1723
Number of edges: 145289

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.6259
Number of communities: 10
Elapsed time: 0 seconds
library(clustree)
Loading required package: ggraph

Attaching package: ‘ggraph’

The following object is masked from ‘package:sp’:

    geometry
clustree(seu.q, prefix = "RNA_snn_res.")

DimPlot(seu.q)

Look at the predictions in the new clusters

Based on the 3 different predictions I can lable the cell types

0 - NPC or early neurons 1 - immature excitatory neurons 2 - NPC or early neurons 3 - RG or Oligos 4- Dopaminergic neurons - possibly early 5 - NPC or early neurons 6 - Radial GLia

I will also find markers and look at a list of neuronal markers

top5 <- ClusterMarkers %>% group_by(cluster) %>% top_n(n=5, wt = avg_log2FC)
DoHeatmap(seu.q, features = top5$gene, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = top5$gene, size = 3, angle = 90,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: SAT1, MTRNR2L12, MT-ND2

write.csv(ClusterMarkers,"/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/Neurons1ClusterMarkers7.csv")

Explore some Gene expression levels

feature_list = c("MKI67","SOX2","POU5F1","DLX2","PAX6","SOX9","HES1","NES","RBFOX3","MAP2","NCAM1","CD24","GRIA2","GRIN2B","GABBR1","GAD1","GAD2","GABRA1","GABRB2","TH","ALDH1A1","LMX1B","NR4A2","CORIN","CALB1","KCNJ6","CXCR4","ITGA6","SLC1A3","CD44","AQP4","S100B", "PDGFRA","OLIG2","MBP","CLDN11","VIM","VCAM1")

DoHeatmap(seu.q, features = feature_list, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = feature_list, size = 3, angle = 90,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: VCAM1, CLDN11, OLIG2, PDGFRA, CD44, SLC1A3, KCNJ6, CORIN, NR4A2, LMX1B, ALDH1A1, GABRA1, GAD2, GABBR1, NCAM1, RBFOX3, NES, SOX9, DLX2, POU5F1, MKI67

DotPlot(seu.q, features = feature_list) +RotatedAxis()


PD_poulin = c("TH","SLC6A3","SLC18A2","SOX6","NDNF","SNCG","ALDH1A1","CALB1","TACR2","SLC17A6","SLC32A1","OTX2","GRP","LPL","CCK","VIP")

DoHeatmap(seu.q, features = PD_poulin, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = PD_poulin, size = 3, angle = 90,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: VIP, CCK, GRP, SLC32A1, TACR2, ALDH1A1, SNCG, NDNF, SOX6, SLC18A2, SLC6A3

DotPlot(seu.q, features = PD_poulin)+RotatedAxis()


ealryNeur = c("DCX","NEUROD1","TBR1")
proliferation = c("PCNA","MKI67")
neuralstem = c("SOX2","NES","PAX6","MASH1")

feature_list <- c("DCX","NEUROD1","TBR1","PCNA","MKI67","SOX2","NES","PAX6","MASH1")
DoHeatmap(seu.q, features = feature_list, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = feature_list, size = 3, angle = 90,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: MASH1, NES, MKI67, PCNA

DotPlot(seu.q, features = feature_list)+RotatedAxis()
Warning in FetchData.Seurat(object = object, vars = features, cells = cells) :
  The following requested variables were not found: MASH1

# no proliferation marker expression  PCNA or MKI67
# cluster 4 DA neurons - shows early neuron marker and low PAX 4
# cluster 3 has higher SOX2 - neuroblast marker / NPC marker

mat_neuron = c("RBFOX3","SYP","DLG45","VAMP1","VAMP2","TUBB3","SYT1","BSN","HOMER1","SLC17A6") 
# NeuN is FOX3 - RBFOX3
# PSD95 also SP-90 or DLG4
# VGLUT2 is SLC17A6
DoHeatmap(seu.q, features = mat_neuron, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = mat_neuron, size = 3, angle = 90,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: HOMER1, BSN, TUBB3, VAMP1, DLG45, SYP, RBFOX3

# cluster 4 also show mature neuron markers
DotPlot(seu.q, features = mat_neuron)+RotatedAxis()
Warning in FetchData.Seurat(object = object, vars = features, cells = cells) :
  The following requested variables were not found: DLG45

# excitatory neuron markers
ex = c("GRIA2","GRIA1","GRIA4","GRIN1","GRIN2B","GRIN2A","GRIN3A","GRIN3","GRIP1","CAMK2A")
DoHeatmap(seu.q, features = ex, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = ex, size = 3, angle = 90, group.bar.height = 0.02,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: CAMK2A, GRIP1, GRIN3, GRIN3A, GRIN2A, GRIN1, GRIA4

DotPlot(seu.q, features = ex)+RotatedAxis()
Warning in FetchData.Seurat(object = object, vars = features, cells = cells) :
  The following requested variables were not found: GRIN3

# inhibitory neuron markers
inh = c("GAD1","GAD2", "GAT1","PVALB","GABR2","GABR1","GBRR1","GABRB2","GABRB1","GABRB3","GABRA6","GABRA1","GABRA4","TRAK2")
DoHeatmap(seu.q, features = inh, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = inh, size = 3, angle = 90, group.bar.height = 0.02,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: TRAK2, GABRA1, GABRA6, GABRB3, GABRB1, GBRR1, GABR1, GABR2, PVALB, GAT1, GAD2

DotPlot(seu.q, features = inh)+RotatedAxis()
Warning in FetchData.Seurat(object = object, vars = features, cells = cells) :
  The following requested variables were not found: GAT1, GABR2, GABR1, GBRR1

# cluster 4 is more excitatory than inhbitory but neither marker set has much expression 

Checkout the Enricher cell type libraries from

N1.c6 <- ClusterMarkers %>% filter(cluster == 6 & avg_log2FC > 0)
genes <- N1.c6$gene

N1.c6.Er <- enrichr(genes, databases = db)
Uploading data to Enrichr... Done.
  Querying Allen_Brain_Atlas_up... Done.
  Querying Descartes_Cell_Types_and_Tissue_2021... Done.
  Querying CellMarker_Augmented_2021... Done.
  Querying Azimuth_Cell_Types_2021... Done.
Parsing results... Done.
plotEnrich(N1.c6.Er[[1]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")

plotEnrich(N1.c6.Er[[2]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")

plotEnrich(N1.c6.Er[[3]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")

plotEnrich(N1.c6.Er[[4]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")


N1.Er.genes.1 <- N1.c6.Er[[1]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.1

N1.Er.genes.2 <- N1.c6.Er[[2]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.2

N1.Er.genes.3 <- N1.c6.Er[[3]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.3

N1.Er.genes.4 <- N1.c6.Er[[4]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.4
NA

Library of tissue cell types for up regulated genes per cluster 0 - hypothalmus, DA A13 1- neural plate, Radial Glia 2 - Neural stem 3 - stromal, astro OPC 4 - Neurons 5 - endothelial, pericyte 6 - maybe neurons maybe not

By the combined information - annotate the clusters in Neurons1

Idents(seu.q) <- 'RNA_snn_res.0.6'
cluster.ids <- c("ImmatureNeurons","Neurons","NPC","OPC-RG","DAneurons",
                 "Other","RG")
unique(seu.q$RNA_snn_res.0.6)
[1] 1 5 0 3 4 2 6
Levels: 0 1 2 3 4 5 6
names(cluster.ids) <- levels(seu.q)
seu.q <- RenameIdents(seu.q, cluster.ids)
seu.q$subgroups <- Idents(seu.q)

DimPlot(seu.q, reduction = "umap", label = TRUE, group.by = 'subgroups', repel = TRUE)



saveRDS(seu.q, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/objs/Neuron1LabledSeu30092022.RDS")

Next Repeat everything for Neurons2

seu.ft <- subset(seu, subset = nFeature_RNA > 300 & nCount_RNA > 500 & nCount_RNA < 10000) 
seu.ft
An object of class Seurat 
33541 features across 9657 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO

Doublet finder

Remove the doublet cells


seu.d <- seu.d[, seu.d@meta.data[, DF.name]== "Singlet"]
dim(seu.d)
[1] 33524  8884
dim(seu)
[1] 33538 34830
# 9657 cells pre filter

Repeat workflow with doublet removed data and find clusters for

clustree(seu.q)

DimPlot(seu.q, reduction = "umap", group.by = 'RNA_snn_res.0.2')

DimPlot(seu.q, reduction = "umap", group.by = 'RNA_snn_res.0.4')

DimPlot(seu.q, reduction = "umap", group.by = 'RNA_snn_res.0.6')

DimPlot(seu.q, reduction = "umap", group.by = 'RNA_snn_res.1.2')

Label cell types using the label transfer




# SNCA and control midbrain organoids 165 days in culture
MBO <- readRDS("/Users/rhalenathomas/Documents/Data/scRNAseq/AST23_BrainComm/MBOclusters_names29072021.rds")

# Midbrain  AIW002 120 days in culture
AIWMBO <- readRDS("/Users/rhalenathomas/Documents/Data/scRNAseq/AIWtrio120days/MOintegratedClusterK123res0.8.names_nov16_2021")

# Midbrain AIW002 60 days in culture

AIW60 <- readRDS("/Users/rhalenathomas/Documents/Data/scRNAseq/AIWtrio60days/AWI002ParkinKOPinkKO60days_labels_14052022.rds")


# query
#seu.q <- readRDS("/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/objs/NeuronsFilteredSeu28092022.RDS")


#first predict with the MBO data
Idents(MBO) <- "cluster_labels"
DefaultAssay(MBO) <- "RNA"

# find the reference anchors
print("finding reference anchors")
[1] "finding reference anchors"
anchors <- FindTransferAnchors(reference = MBO ,query = seu.q, dims = 1:25)
Performing PCA on the provided reference using 1997 features as input.
Projecting cell embeddings
Finding neighborhoods
Finding anchors
    Found 1228 anchors
Filtering anchors
    Retained 528 anchors
as(<ngCMatrix>, "dgCMatrix") is deprecated since Matrix 1.5-0; do as(., "dMatrix") instead
print("getting predictions")
[1] "getting predictions"
predictions <- TransferData(anchorset = anchors, refdata = MBO$cluster_labels)
Finding integration vectors
Finding integration vector weights
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Predicting cell labels
seu.q <- AddMetaData(seu.q, metadata = predictions)
print(table(seu.q$predicted.id))

       Epithelial Neural Precursors        Neurons-DA         Neurons-e 
                9               191               347               602 
 Oligodendrocytes               RGa              RGd1              RGd2 
             7045                 5               666                19 
Idents(seu.q) <- 'predicted.id'
# add new dataslot for MBO predicted ID to make the next prediction
seu.q$MBOAST23.pred <- Idents(seu.q)
DimPlot(seu.q, group.by = 'MBOAST23.pred', label = TRUE)

 
## check the proportion of cell types predicted in each cluster
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.2, seu.q$predicted.id))
pr.t.lables <- as.data.frame(prop.table(table(seu.q$RNA_snn_res.0.2, seu.q$predicted.id)))
t.lables$Freq <- as.double(t.lables$Freq)


# try bar chart
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity")


# clusters don't break up by the predicted cell types

############ another predictions now using the AIW organoids

Idents(AIWMBO) <- "res08names"
DefaultAssay(AIWMBO) <- "RNA"

anchors <- FindTransferAnchors(reference = AIWMBO ,query = seu.q, dims = 1:25)
Performing PCA on the provided reference using 2000 features as input.
Projecting cell embeddings
Finding neighborhoods
Finding anchors
    Found 3590 anchors
Filtering anchors
    Retained 1923 anchors
print("getting predictions")
[1] "getting predictions"
predictions <- TransferData(anchorset = anchors, refdata = AIWMBO$res08names)
Finding integration vectors
Finding integration vector weights
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Predicting cell labels
seu.q <- AddMetaData(seu.q, metadata = predictions)
print(table(seu.q$predicted.id))

       epithelial        Neurons_DA Neurons_early_inh               OPC 
               37               492              5556                32 
              RGa              RGd1              RGd3 
             2732                18                17 
Idents(seu.q) <- 'predicted.id'
# add new dataslot for MBO predicted ID to make the next prediction
seu.q$MBOAIW.pred <- Idents(seu.q)
DimPlot(seu.q, group.by = 'MBOAIW.pred', label = TRUE)

 
## check the proportion of cell types predicted in each cluster
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.2, seu.q$predicted.id))
pr.t.lables <- as.data.frame(prop.table(table(seu.q$RNA_snn_res.0.2, seu.q$predicted.id)))
t.lables$Freq <- as.double(t.lables$Freq)


# try bar chart
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity")


# the predicted cell types make more sense from the AIW002 organoid
# now predict with the AIW002 60 days organoid

Idents(AIW60) <- "cluster.ids"
DefaultAssay(AIW60) <- "RNA"

anchors <- FindTransferAnchors(reference = AIW60, query = seu.q, dims = 1:25)
Performing PCA on the provided reference using 1999 features as input.
Projecting cell embeddings
Finding neighborhoods
Finding anchors
    Found 3130 anchors
Filtering anchors
    Retained 1215 anchors
print("getting predictions")
[1] "getting predictions"
predictions <- TransferData(anchorset = anchors, refdata = AIW60$cluster.ids) 
Finding integration vectors
Finding integration vector weights
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Predicting cell labels
seu.q <- AddMetaData(seu.q, metadata = predictions)
print(table(seu.q$predicted.id))

Dopaminergic Neurons early 1            Neural Epithelial 
                         950                           15 
           Neural Precursors                Radial Glia 1 
                        6332                         1572 
               Radial Glia 2 
                          15 
Idents(seu.q) <- 'predicted.id'
# add new dataslot for MBO predicted ID to make the next prediction
seu.q$AIW60.pred <- Idents(seu.q)
DimPlot(seu.q, group.by = 'AIW60.pred', label = TRUE)

 
## check the proportion of cell types predicted in each cluster
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.2, seu.q$predicted.id))
pr.t.lables <- as.data.frame(prop.table(table(seu.q$RNA_snn_res.0.2, seu.q$predicted.id)))
t.lables$Freq <- as.double(t.lables$Freq)


# try bar chart
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity")


# save ojbect with predicitons
saveRDS(seu.q, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/objs/Neurons2PredictionsSeu30092022.RDS")

See the top predictions for each cluster in Neurons2 res 06

What cell types are predicted across the 3 references

0 - Neurons early , NPC, neurons excitatory 1 - Neurons early, NPC 2 - Neurons early, NPC, neurons excitatory some DA neurons 3 - Oligo, RG, 4 - Excitatory neurons, NPC, early neurons 5 - DA neurons, early DA neurons 6 - neurons immature NPC 7 - DA neurons 8 - RG, oligo, OPC, NPC 9 - Radial Glia 10 - NPC, neurons, oligo 11 - NPC, neurons, oligo

Find cluster markers and see how those would annotate

Idents(seu.q) <- 'RNA_snn_res.0.6'
ClusterMarkers <- FindAllMarkers(seu.q, only.pos = TRUE)
Calculating cluster 0

  |                                                  | 0 % ~calculating  
  |++++++++                                          | 14% ~00s          
  |+++++++++++++++                                   | 29% ~00s          
  |++++++++++++++++++++++                            | 43% ~00s          
  |+++++++++++++++++++++++++++++                     | 57% ~00s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=00s  
Calculating cluster 1

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~03s          
  |++                                                | 2 % ~03s          
  |++                                                | 4 % ~03s          
  |+++                                               | 5 % ~03s          
  |+++                                               | 6 % ~03s          
  |++++                                              | 7 % ~03s          
  |+++++                                             | 8 % ~03s          
  |+++++                                             | 9 % ~03s          
  |++++++                                            | 11% ~03s          
  |++++++                                            | 12% ~03s          
  |+++++++                                           | 13% ~03s          
  |++++++++                                          | 14% ~03s          
  |++++++++                                          | 15% ~02s          
  |+++++++++                                         | 16% ~02s          
  |+++++++++                                         | 18% ~02s          
  |++++++++++                                        | 19% ~02s          
  |++++++++++                                        | 20% ~02s          
  |+++++++++++                                       | 21% ~02s          
  |++++++++++++                                      | 22% ~02s          
  |++++++++++++                                      | 24% ~02s          
  |+++++++++++++                                     | 25% ~02s          
  |+++++++++++++                                     | 26% ~02s          
  |++++++++++++++                                    | 27% ~02s          
  |+++++++++++++++                                   | 28% ~02s          
  |+++++++++++++++                                   | 29% ~02s          
  |++++++++++++++++                                  | 31% ~02s          
  |++++++++++++++++                                  | 32% ~02s          
  |+++++++++++++++++                                 | 33% ~02s          
  |++++++++++++++++++                                | 34% ~02s          
  |++++++++++++++++++                                | 35% ~02s          
  |+++++++++++++++++++                               | 36% ~02s          
  |+++++++++++++++++++                               | 38% ~02s          
  |++++++++++++++++++++                              | 39% ~02s          
  |++++++++++++++++++++                              | 40% ~02s          
  |+++++++++++++++++++++                             | 41% ~02s          
  |++++++++++++++++++++++                            | 42% ~02s          
  |++++++++++++++++++++++                            | 44% ~02s          
  |+++++++++++++++++++++++                           | 45% ~02s          
  |+++++++++++++++++++++++                           | 46% ~02s          
  |++++++++++++++++++++++++                          | 47% ~02s          
  |+++++++++++++++++++++++++                         | 48% ~02s          
  |+++++++++++++++++++++++++                         | 49% ~02s          
  |++++++++++++++++++++++++++                        | 51% ~02s          
  |++++++++++++++++++++++++++                        | 52% ~02s          
  |+++++++++++++++++++++++++++                       | 53% ~02s          
  |++++++++++++++++++++++++++++                      | 54% ~01s          
  |++++++++++++++++++++++++++++                      | 55% ~01s          
  |+++++++++++++++++++++++++++++                     | 56% ~01s          
  |+++++++++++++++++++++++++++++                     | 58% ~01s          
  |++++++++++++++++++++++++++++++                    | 59% ~01s          
  |++++++++++++++++++++++++++++++                    | 60% ~01s          
  |+++++++++++++++++++++++++++++++                   | 61% ~01s          
  |++++++++++++++++++++++++++++++++                  | 62% ~01s          
  |++++++++++++++++++++++++++++++++                  | 64% ~01s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~01s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~01s          
  |++++++++++++++++++++++++++++++++++                | 67% ~01s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~01s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~01s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~01s          
  |++++++++++++++++++++++++++++++++++++              | 72% ~01s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~01s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~01s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~01s          
  |+++++++++++++++++++++++++++++++++++++++           | 76% ~01s          
  |+++++++++++++++++++++++++++++++++++++++           | 78% ~01s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~01s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 82% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 94% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=03s  
Calculating cluster 2

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~03s          
  |++                                                | 3 % ~03s          
  |++                                                | 4 % ~03s          
  |+++                                               | 5 % ~03s          
  |++++                                              | 7 % ~03s          
  |++++                                              | 8 % ~03s          
  |+++++                                             | 9 % ~03s          
  |++++++                                            | 11% ~03s          
  |++++++                                            | 12% ~03s          
  |+++++++                                           | 13% ~03s          
  |++++++++                                          | 15% ~02s          
  |++++++++                                          | 16% ~02s          
  |+++++++++                                         | 17% ~02s          
  |++++++++++                                        | 19% ~02s          
  |++++++++++                                        | 20% ~02s          
  |+++++++++++                                       | 21% ~02s          
  |++++++++++++                                      | 23% ~02s          
  |++++++++++++                                      | 24% ~02s          
  |+++++++++++++                                     | 25% ~02s          
  |++++++++++++++                                    | 27% ~02s          
  |++++++++++++++                                    | 28% ~02s          
  |+++++++++++++++                                   | 29% ~02s          
  |++++++++++++++++                                  | 31% ~02s          
  |++++++++++++++++                                  | 32% ~02s          
  |+++++++++++++++++                                 | 33% ~02s          
  |++++++++++++++++++                                | 35% ~02s          
  |++++++++++++++++++                                | 36% ~02s          
  |+++++++++++++++++++                               | 37% ~02s          
  |++++++++++++++++++++                              | 39% ~02s          
  |++++++++++++++++++++                              | 40% ~02s          
  |+++++++++++++++++++++                             | 41% ~02s          
  |++++++++++++++++++++++                            | 43% ~02s          
  |++++++++++++++++++++++                            | 44% ~02s          
  |+++++++++++++++++++++++                           | 45% ~02s          
  |++++++++++++++++++++++++                          | 47% ~01s          
  |++++++++++++++++++++++++                          | 48% ~01s          
  |+++++++++++++++++++++++++                         | 49% ~01s          
  |++++++++++++++++++++++++++                        | 51% ~01s          
  |++++++++++++++++++++++++++                        | 52% ~01s          
  |+++++++++++++++++++++++++++                       | 53% ~01s          
  |++++++++++++++++++++++++++++                      | 55% ~01s          
  |++++++++++++++++++++++++++++                      | 56% ~01s          
  |+++++++++++++++++++++++++++++                     | 57% ~01s          
  |++++++++++++++++++++++++++++++                    | 59% ~01s          
  |++++++++++++++++++++++++++++++                    | 60% ~01s          
  |+++++++++++++++++++++++++++++++                   | 61% ~01s          
  |++++++++++++++++++++++++++++++++                  | 63% ~01s          
  |++++++++++++++++++++++++++++++++                  | 64% ~01s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~01s          
  |++++++++++++++++++++++++++++++++++                | 67% ~01s          
  |++++++++++++++++++++++++++++++++++                | 68% ~01s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~01s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~01s          
  |++++++++++++++++++++++++++++++++++++              | 72% ~01s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~01s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~01s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~01s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~01s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~01s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=03s  
Calculating cluster 3

  |                                                  | 0 % ~calculating  
  |+                                                 | 2 % ~02s          
  |++                                                | 3 % ~02s          
  |+++                                               | 5 % ~02s          
  |++++                                              | 6 % ~02s          
  |++++                                              | 8 % ~02s          
  |+++++                                             | 9 % ~02s          
  |++++++                                            | 11% ~02s          
  |+++++++                                           | 12% ~02s          
  |+++++++                                           | 14% ~02s          
  |++++++++                                          | 15% ~02s          
  |+++++++++                                         | 17% ~02s          
  |++++++++++                                        | 18% ~02s          
  |++++++++++                                        | 20% ~02s          
  |+++++++++++                                       | 21% ~02s          
  |++++++++++++                                      | 23% ~02s          
  |+++++++++++++                                     | 24% ~02s          
  |+++++++++++++                                     | 26% ~02s          
  |++++++++++++++                                    | 27% ~02s          
  |+++++++++++++++                                   | 29% ~02s          
  |++++++++++++++++                                  | 30% ~02s          
  |++++++++++++++++                                  | 32% ~02s          
  |+++++++++++++++++                                 | 33% ~02s          
  |++++++++++++++++++                                | 35% ~02s          
  |+++++++++++++++++++                               | 36% ~02s          
  |+++++++++++++++++++                               | 38% ~02s          
  |++++++++++++++++++++                              | 39% ~02s          
  |+++++++++++++++++++++                             | 41% ~02s          
  |++++++++++++++++++++++                            | 42% ~02s          
  |++++++++++++++++++++++                            | 44% ~02s          
  |+++++++++++++++++++++++                           | 45% ~02s          
  |++++++++++++++++++++++++                          | 47% ~01s          
  |+++++++++++++++++++++++++                         | 48% ~01s          
  |+++++++++++++++++++++++++                         | 50% ~01s          
  |++++++++++++++++++++++++++                        | 52% ~01s          
  |+++++++++++++++++++++++++++                       | 53% ~01s          
  |++++++++++++++++++++++++++++                      | 55% ~01s          
  |+++++++++++++++++++++++++++++                     | 56% ~01s          
  |+++++++++++++++++++++++++++++                     | 58% ~01s          
  |++++++++++++++++++++++++++++++                    | 59% ~01s          
  |+++++++++++++++++++++++++++++++                   | 61% ~01s          
  |++++++++++++++++++++++++++++++++                  | 62% ~01s          
  |++++++++++++++++++++++++++++++++                  | 64% ~01s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~01s          
  |++++++++++++++++++++++++++++++++++                | 67% ~01s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~01s          
  |+++++++++++++++++++++++++++++++++++               | 70% ~01s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~01s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~01s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~01s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~01s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~01s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++         | 80% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++         | 82% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=03s  
Calculating cluster 4

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~11s          
  |++                                                | 2 % ~10s          
  |++                                                | 3 % ~10s          
  |+++                                               | 4 % ~10s          
  |+++                                               | 5 % ~10s          
  |++++                                              | 7 % ~10s          
  |++++                                              | 8 % ~09s          
  |+++++                                             | 9 % ~09s          
  |+++++                                             | 10% ~09s          
  |++++++                                            | 11% ~09s          
  |+++++++                                           | 12% ~09s          
  |+++++++                                           | 13% ~09s          
  |++++++++                                          | 14% ~09s          
  |++++++++                                          | 15% ~09s          
  |+++++++++                                         | 16% ~09s          
  |+++++++++                                         | 18% ~09s          
  |++++++++++                                        | 19% ~09s          
  |++++++++++                                        | 20% ~08s          
  |+++++++++++                                       | 21% ~08s          
  |+++++++++++                                       | 22% ~08s          
  |++++++++++++                                      | 23% ~08s          
  |+++++++++++++                                     | 24% ~08s          
  |+++++++++++++                                     | 25% ~08s          
  |++++++++++++++                                    | 26% ~08s          
  |++++++++++++++                                    | 27% ~08s          
  |+++++++++++++++                                   | 29% ~08s          
  |+++++++++++++++                                   | 30% ~07s          
  |++++++++++++++++                                  | 31% ~07s          
  |++++++++++++++++                                  | 32% ~07s          
  |+++++++++++++++++                                 | 33% ~07s          
  |++++++++++++++++++                                | 34% ~07s          
  |++++++++++++++++++                                | 35% ~07s          
  |+++++++++++++++++++                               | 36% ~07s          
  |+++++++++++++++++++                               | 37% ~07s          
  |++++++++++++++++++++                              | 38% ~07s          
  |++++++++++++++++++++                              | 40% ~06s          
  |+++++++++++++++++++++                             | 41% ~06s          
  |+++++++++++++++++++++                             | 42% ~06s          
  |++++++++++++++++++++++                            | 43% ~06s          
  |++++++++++++++++++++++                            | 44% ~06s          
  |+++++++++++++++++++++++                           | 45% ~06s          
  |++++++++++++++++++++++++                          | 46% ~06s          
  |++++++++++++++++++++++++                          | 47% ~06s          
  |+++++++++++++++++++++++++                         | 48% ~06s          
  |+++++++++++++++++++++++++                         | 49% ~05s          
  |++++++++++++++++++++++++++                        | 51% ~05s          
  |++++++++++++++++++++++++++                        | 52% ~05s          
  |+++++++++++++++++++++++++++                       | 53% ~05s          
  |+++++++++++++++++++++++++++                       | 54% ~05s          
  |++++++++++++++++++++++++++++                      | 55% ~05s          
  |+++++++++++++++++++++++++++++                     | 56% ~05s          
  |+++++++++++++++++++++++++++++                     | 57% ~05s          
  |++++++++++++++++++++++++++++++                    | 58% ~04s          
  |++++++++++++++++++++++++++++++                    | 59% ~04s          
  |+++++++++++++++++++++++++++++++                   | 60% ~04s          
  |+++++++++++++++++++++++++++++++                   | 62% ~04s          
  |++++++++++++++++++++++++++++++++                  | 63% ~04s          
  |++++++++++++++++++++++++++++++++                  | 64% ~04s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~04s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~04s          
  |++++++++++++++++++++++++++++++++++                | 67% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~03s          
  |++++++++++++++++++++++++++++++++++++              | 70% ~03s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~03s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~03s          
  |+++++++++++++++++++++++++++++++++++++             | 74% ~03s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~03s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~03s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 78% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 80% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 82% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=10s  
Calculating cluster 5

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~24s          
  |++                                                | 2 % ~24s          
  |++                                                | 3 % ~24s          
  |+++                                               | 4 % ~24s          
  |+++                                               | 5 % ~23s          
  |++++                                              | 6 % ~23s          
  |++++                                              | 7 % ~23s          
  |+++++                                             | 8 % ~23s          
  |+++++                                             | 9 % ~22s          
  |++++++                                            | 11% ~22s          
  |++++++                                            | 12% ~22s          
  |+++++++                                           | 13% ~22s          
  |+++++++                                           | 14% ~21s          
  |++++++++                                          | 15% ~21s          
  |++++++++                                          | 16% ~21s          
  |+++++++++                                         | 17% ~21s          
  |+++++++++                                         | 18% ~20s          
  |++++++++++                                        | 19% ~20s          
  |++++++++++                                        | 20% ~20s          
  |+++++++++++                                       | 21% ~20s          
  |++++++++++++                                      | 22% ~19s          
  |++++++++++++                                      | 23% ~19s          
  |+++++++++++++                                     | 24% ~19s          
  |+++++++++++++                                     | 25% ~19s          
  |++++++++++++++                                    | 26% ~18s          
  |++++++++++++++                                    | 27% ~18s          
  |+++++++++++++++                                   | 28% ~18s          
  |+++++++++++++++                                   | 29% ~18s          
  |++++++++++++++++                                  | 31% ~17s          
  |++++++++++++++++                                  | 32% ~17s          
  |+++++++++++++++++                                 | 33% ~17s          
  |+++++++++++++++++                                 | 34% ~16s          
  |++++++++++++++++++                                | 35% ~16s          
  |++++++++++++++++++                                | 36% ~16s          
  |+++++++++++++++++++                               | 37% ~16s          
  |+++++++++++++++++++                               | 38% ~15s          
  |++++++++++++++++++++                              | 39% ~15s          
  |++++++++++++++++++++                              | 40% ~15s          
  |+++++++++++++++++++++                             | 41% ~15s          
  |++++++++++++++++++++++                            | 42% ~14s          
  |++++++++++++++++++++++                            | 43% ~14s          
  |+++++++++++++++++++++++                           | 44% ~14s          
  |+++++++++++++++++++++++                           | 45% ~14s          
  |++++++++++++++++++++++++                          | 46% ~13s          
  |++++++++++++++++++++++++                          | 47% ~13s          
  |+++++++++++++++++++++++++                         | 48% ~13s          
  |+++++++++++++++++++++++++                         | 49% ~13s          
  |++++++++++++++++++++++++++                        | 51% ~12s          
  |++++++++++++++++++++++++++                        | 52% ~12s          
  |+++++++++++++++++++++++++++                       | 53% ~12s          
  |+++++++++++++++++++++++++++                       | 54% ~12s          
  |++++++++++++++++++++++++++++                      | 55% ~11s          
  |++++++++++++++++++++++++++++                      | 56% ~11s          
  |+++++++++++++++++++++++++++++                     | 57% ~11s          
  |+++++++++++++++++++++++++++++                     | 58% ~10s          
  |++++++++++++++++++++++++++++++                    | 59% ~10s          
  |++++++++++++++++++++++++++++++                    | 60% ~10s          
  |+++++++++++++++++++++++++++++++                   | 61% ~10s          
  |++++++++++++++++++++++++++++++++                  | 62% ~09s          
  |++++++++++++++++++++++++++++++++                  | 63% ~09s          
  |+++++++++++++++++++++++++++++++++                 | 64% ~09s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~09s          
  |++++++++++++++++++++++++++++++++++                | 66% ~08s          
  |++++++++++++++++++++++++++++++++++                | 67% ~08s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~08s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~08s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~07s          
  |++++++++++++++++++++++++++++++++++++              | 72% ~07s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~07s          
  |+++++++++++++++++++++++++++++++++++++             | 74% ~07s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~06s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~06s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~06s          
  |+++++++++++++++++++++++++++++++++++++++           | 78% ~06s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~05s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~05s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~05s          
  |++++++++++++++++++++++++++++++++++++++++++        | 82% ~04s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~04s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~04s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~04s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~03s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~03s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=25s  
Calculating cluster 6

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~05s          
  |++                                                | 2 % ~04s          
  |++                                                | 4 % ~04s          
  |+++                                               | 5 % ~04s          
  |+++                                               | 6 % ~04s          
  |++++                                              | 7 % ~04s          
  |+++++                                             | 8 % ~04s          
  |+++++                                             | 9 % ~04s          
  |++++++                                            | 11% ~04s          
  |++++++                                            | 12% ~04s          
  |+++++++                                           | 13% ~04s          
  |++++++++                                          | 14% ~04s          
  |++++++++                                          | 15% ~04s          
  |+++++++++                                         | 16% ~03s          
  |+++++++++                                         | 18% ~03s          
  |++++++++++                                        | 19% ~03s          
  |++++++++++                                        | 20% ~03s          
  |+++++++++++                                       | 21% ~03s          
  |++++++++++++                                      | 22% ~03s          
  |++++++++++++                                      | 24% ~03s          
  |+++++++++++++                                     | 25% ~03s          
  |+++++++++++++                                     | 26% ~03s          
  |++++++++++++++                                    | 27% ~03s          
  |+++++++++++++++                                   | 28% ~03s          
  |+++++++++++++++                                   | 29% ~03s          
  |++++++++++++++++                                  | 31% ~03s          
  |++++++++++++++++                                  | 32% ~03s          
  |+++++++++++++++++                                 | 33% ~03s          
  |++++++++++++++++++                                | 34% ~03s          
  |++++++++++++++++++                                | 35% ~03s          
  |+++++++++++++++++++                               | 36% ~03s          
  |+++++++++++++++++++                               | 38% ~03s          
  |++++++++++++++++++++                              | 39% ~03s          
  |++++++++++++++++++++                              | 40% ~03s          
  |+++++++++++++++++++++                             | 41% ~02s          
  |++++++++++++++++++++++                            | 42% ~02s          
  |++++++++++++++++++++++                            | 44% ~02s          
  |+++++++++++++++++++++++                           | 45% ~02s          
  |+++++++++++++++++++++++                           | 46% ~02s          
  |++++++++++++++++++++++++                          | 47% ~02s          
  |+++++++++++++++++++++++++                         | 48% ~02s          
  |+++++++++++++++++++++++++                         | 49% ~02s          
  |++++++++++++++++++++++++++                        | 51% ~02s          
  |++++++++++++++++++++++++++                        | 52% ~02s          
  |+++++++++++++++++++++++++++                       | 53% ~02s          
  |++++++++++++++++++++++++++++                      | 54% ~02s          
  |++++++++++++++++++++++++++++                      | 55% ~02s          
  |+++++++++++++++++++++++++++++                     | 56% ~02s          
  |+++++++++++++++++++++++++++++                     | 58% ~02s          
  |++++++++++++++++++++++++++++++                    | 59% ~02s          
  |++++++++++++++++++++++++++++++                    | 60% ~02s          
  |+++++++++++++++++++++++++++++++                   | 61% ~02s          
  |++++++++++++++++++++++++++++++++                  | 62% ~02s          
  |++++++++++++++++++++++++++++++++                  | 64% ~02s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~01s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~01s          
  |++++++++++++++++++++++++++++++++++                | 67% ~01s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~01s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~01s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~01s          
  |++++++++++++++++++++++++++++++++++++              | 72% ~01s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~01s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~01s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~01s          
  |+++++++++++++++++++++++++++++++++++++++           | 76% ~01s          
  |+++++++++++++++++++++++++++++++++++++++           | 78% ~01s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~01s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 82% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 94% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=04s  
Calculating cluster 7

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~32s          
  |++                                                | 2 % ~32s          
  |++                                                | 3 % ~32s          
  |+++                                               | 4 % ~32s          
  |+++                                               | 5 % ~31s          
  |++++                                              | 6 % ~31s          
  |++++                                              | 7 % ~31s          
  |+++++                                             | 8 % ~30s          
  |+++++                                             | 9 % ~30s          
  |++++++                                            | 10% ~30s          
  |++++++                                            | 11% ~29s          
  |+++++++                                           | 12% ~29s          
  |+++++++                                           | 14% ~29s          
  |++++++++                                          | 15% ~28s          
  |++++++++                                          | 16% ~28s          
  |+++++++++                                         | 17% ~27s          
  |+++++++++                                         | 18% ~27s          
  |++++++++++                                        | 19% ~27s          
  |++++++++++                                        | 20% ~26s          
  |+++++++++++                                       | 21% ~26s          
  |+++++++++++                                       | 22% ~26s          
  |++++++++++++                                      | 23% ~25s          
  |++++++++++++                                      | 24% ~25s          
  |+++++++++++++                                     | 25% ~25s          
  |++++++++++++++                                    | 26% ~24s          
  |++++++++++++++                                    | 27% ~24s          
  |+++++++++++++++                                   | 28% ~24s          
  |+++++++++++++++                                   | 29% ~24s          
  |++++++++++++++++                                  | 30% ~23s          
  |++++++++++++++++                                  | 31% ~23s          
  |+++++++++++++++++                                 | 32% ~22s          
  |+++++++++++++++++                                 | 33% ~22s          
  |++++++++++++++++++                                | 34% ~22s          
  |++++++++++++++++++                                | 35% ~21s          
  |+++++++++++++++++++                               | 36% ~21s          
  |+++++++++++++++++++                               | 38% ~21s          
  |++++++++++++++++++++                              | 39% ~20s          
  |++++++++++++++++++++                              | 40% ~20s          
  |+++++++++++++++++++++                             | 41% ~20s          
  |+++++++++++++++++++++                             | 42% ~19s          
  |++++++++++++++++++++++                            | 43% ~19s          
  |++++++++++++++++++++++                            | 44% ~18s          
  |+++++++++++++++++++++++                           | 45% ~18s          
  |+++++++++++++++++++++++                           | 46% ~18s          
  |++++++++++++++++++++++++                          | 47% ~17s          
  |++++++++++++++++++++++++                          | 48% ~17s          
  |+++++++++++++++++++++++++                         | 49% ~17s          
  |+++++++++++++++++++++++++                         | 50% ~16s          
  |++++++++++++++++++++++++++                        | 51% ~16s          
  |+++++++++++++++++++++++++++                       | 52% ~16s          
  |+++++++++++++++++++++++++++                       | 53% ~15s          
  |++++++++++++++++++++++++++++                      | 54% ~15s          
  |++++++++++++++++++++++++++++                      | 55% ~15s          
  |+++++++++++++++++++++++++++++                     | 56% ~14s          
  |+++++++++++++++++++++++++++++                     | 57% ~14s          
  |++++++++++++++++++++++++++++++                    | 58% ~14s          
  |++++++++++++++++++++++++++++++                    | 59% ~13s          
  |+++++++++++++++++++++++++++++++                   | 60% ~13s          
  |+++++++++++++++++++++++++++++++                   | 61% ~13s          
  |++++++++++++++++++++++++++++++++                  | 62% ~12s          
  |++++++++++++++++++++++++++++++++                  | 64% ~12s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~11s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~11s          
  |++++++++++++++++++++++++++++++++++                | 67% ~11s          
  |++++++++++++++++++++++++++++++++++                | 68% ~10s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~10s          
  |+++++++++++++++++++++++++++++++++++               | 70% ~10s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~09s          
  |++++++++++++++++++++++++++++++++++++              | 72% ~09s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~09s          
  |+++++++++++++++++++++++++++++++++++++             | 74% ~08s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~08s          
  |+++++++++++++++++++++++++++++++++++++++           | 76% ~08s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~07s          
  |++++++++++++++++++++++++++++++++++++++++          | 78% ~07s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~07s          
  |+++++++++++++++++++++++++++++++++++++++++         | 80% ~06s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~06s          
  |++++++++++++++++++++++++++++++++++++++++++        | 82% ~06s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~05s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~05s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~05s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~04s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~04s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~04s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~03s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~03s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=32s  
Calculating cluster 8

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~10s          
  |++                                                | 2 % ~09s          
  |++                                                | 3 % ~09s          
  |+++                                               | 4 % ~09s          
  |+++                                               | 6 % ~09s          
  |++++                                              | 7 % ~09s          
  |++++                                              | 8 % ~09s          
  |+++++                                             | 9 % ~09s          
  |++++++                                            | 10% ~09s          
  |++++++                                            | 11% ~08s          
  |+++++++                                           | 12% ~08s          
  |+++++++                                           | 13% ~08s          
  |++++++++                                          | 15% ~08s          
  |++++++++                                          | 16% ~08s          
  |+++++++++                                         | 17% ~08s          
  |+++++++++                                         | 18% ~08s          
  |++++++++++                                        | 19% ~08s          
  |+++++++++++                                       | 20% ~08s          
  |+++++++++++                                       | 21% ~08s          
  |++++++++++++                                      | 22% ~07s          
  |++++++++++++                                      | 24% ~07s          
  |+++++++++++++                                     | 25% ~07s          
  |+++++++++++++                                     | 26% ~07s          
  |++++++++++++++                                    | 27% ~07s          
  |+++++++++++++++                                   | 28% ~07s          
  |+++++++++++++++                                   | 29% ~07s          
  |++++++++++++++++                                  | 30% ~07s          
  |++++++++++++++++                                  | 31% ~07s          
  |+++++++++++++++++                                 | 33% ~07s          
  |+++++++++++++++++                                 | 34% ~06s          
  |++++++++++++++++++                                | 35% ~06s          
  |++++++++++++++++++                                | 36% ~06s          
  |+++++++++++++++++++                               | 37% ~06s          
  |++++++++++++++++++++                              | 38% ~06s          
  |++++++++++++++++++++                              | 39% ~06s          
  |+++++++++++++++++++++                             | 40% ~06s          
  |+++++++++++++++++++++                             | 42% ~06s          
  |++++++++++++++++++++++                            | 43% ~06s          
  |++++++++++++++++++++++                            | 44% ~05s          
  |+++++++++++++++++++++++                           | 45% ~05s          
  |++++++++++++++++++++++++                          | 46% ~05s          
  |++++++++++++++++++++++++                          | 47% ~05s          
  |+++++++++++++++++++++++++                         | 48% ~05s          
  |+++++++++++++++++++++++++                         | 49% ~05s          
  |++++++++++++++++++++++++++                        | 51% ~05s          
  |++++++++++++++++++++++++++                        | 52% ~05s          
  |+++++++++++++++++++++++++++                       | 53% ~05s          
  |+++++++++++++++++++++++++++                       | 54% ~04s          
  |++++++++++++++++++++++++++++                      | 55% ~04s          
  |+++++++++++++++++++++++++++++                     | 56% ~04s          
  |+++++++++++++++++++++++++++++                     | 57% ~04s          
  |++++++++++++++++++++++++++++++                    | 58% ~04s          
  |++++++++++++++++++++++++++++++                    | 60% ~04s          
  |+++++++++++++++++++++++++++++++                   | 61% ~04s          
  |+++++++++++++++++++++++++++++++                   | 62% ~04s          
  |++++++++++++++++++++++++++++++++                  | 63% ~04s          
  |+++++++++++++++++++++++++++++++++                 | 64% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~03s          
  |++++++++++++++++++++++++++++++++++                | 66% ~03s          
  |++++++++++++++++++++++++++++++++++                | 67% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 70% ~03s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~03s          
  |++++++++++++++++++++++++++++++++++++              | 72% ~03s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~03s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~03s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 76% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 78% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 82% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 94% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=10s  
Calculating cluster 9

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~14s          
  |++                                                | 2 % ~14s          
  |++                                                | 3 % ~14s          
  |+++                                               | 4 % ~14s          
  |+++                                               | 5 % ~13s          
  |++++                                              | 6 % ~13s          
  |++++                                              | 8 % ~13s          
  |+++++                                             | 9 % ~13s          
  |+++++                                             | 10% ~13s          
  |++++++                                            | 11% ~13s          
  |++++++                                            | 12% ~13s          
  |+++++++                                           | 13% ~12s          
  |+++++++                                           | 14% ~12s          
  |++++++++                                          | 15% ~12s          
  |+++++++++                                         | 16% ~12s          
  |+++++++++                                         | 17% ~12s          
  |++++++++++                                        | 18% ~12s          
  |++++++++++                                        | 19% ~12s          
  |+++++++++++                                       | 20% ~11s          
  |+++++++++++                                       | 22% ~11s          
  |++++++++++++                                      | 23% ~11s          
  |++++++++++++                                      | 24% ~11s          
  |+++++++++++++                                     | 25% ~11s          
  |+++++++++++++                                     | 26% ~11s          
  |++++++++++++++                                    | 27% ~10s          
  |++++++++++++++                                    | 28% ~10s          
  |+++++++++++++++                                   | 29% ~10s          
  |++++++++++++++++                                  | 30% ~10s          
  |++++++++++++++++                                  | 31% ~10s          
  |+++++++++++++++++                                 | 32% ~10s          
  |+++++++++++++++++                                 | 33% ~10s          
  |++++++++++++++++++                                | 34% ~09s          
  |++++++++++++++++++                                | 35% ~09s          
  |+++++++++++++++++++                               | 37% ~09s          
  |+++++++++++++++++++                               | 38% ~09s          
  |++++++++++++++++++++                              | 39% ~09s          
  |++++++++++++++++++++                              | 40% ~09s          
  |+++++++++++++++++++++                             | 41% ~08s          
  |+++++++++++++++++++++                             | 42% ~08s          
  |++++++++++++++++++++++                            | 43% ~08s          
  |+++++++++++++++++++++++                           | 44% ~08s          
  |+++++++++++++++++++++++                           | 45% ~08s          
  |++++++++++++++++++++++++                          | 46% ~08s          
  |++++++++++++++++++++++++                          | 47% ~08s          
  |+++++++++++++++++++++++++                         | 48% ~08s          
  |+++++++++++++++++++++++++                         | 49% ~07s          
  |++++++++++++++++++++++++++                        | 51% ~07s          
  |++++++++++++++++++++++++++                        | 52% ~07s          
  |+++++++++++++++++++++++++++                       | 53% ~07s          
  |+++++++++++++++++++++++++++                       | 54% ~07s          
  |++++++++++++++++++++++++++++                      | 55% ~07s          
  |++++++++++++++++++++++++++++                      | 56% ~06s          
  |+++++++++++++++++++++++++++++                     | 57% ~06s          
  |++++++++++++++++++++++++++++++                    | 58% ~06s          
  |++++++++++++++++++++++++++++++                    | 59% ~06s          
  |+++++++++++++++++++++++++++++++                   | 60% ~06s          
  |+++++++++++++++++++++++++++++++                   | 61% ~06s          
  |++++++++++++++++++++++++++++++++                  | 62% ~05s          
  |++++++++++++++++++++++++++++++++                  | 63% ~05s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~05s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~05s          
  |++++++++++++++++++++++++++++++++++                | 67% ~05s          
  |++++++++++++++++++++++++++++++++++                | 68% ~05s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~04s          
  |+++++++++++++++++++++++++++++++++++               | 70% ~04s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~04s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~04s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~04s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~04s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~04s          
  |+++++++++++++++++++++++++++++++++++++++           | 76% ~03s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~03s          
  |++++++++++++++++++++++++++++++++++++++++          | 78% ~03s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++         | 82% ~03s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=14s  
Calculating cluster 10

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~08s          
  |++                                                | 2 % ~07s          
  |++                                                | 3 % ~08s          
  |+++                                               | 5 % ~07s          
  |+++                                               | 6 % ~07s          
  |++++                                              | 7 % ~07s          
  |+++++                                             | 8 % ~07s          
  |+++++                                             | 9 % ~07s          
  |++++++                                            | 10% ~07s          
  |++++++                                            | 11% ~07s          
  |+++++++                                           | 13% ~06s          
  |+++++++                                           | 14% ~06s          
  |++++++++                                          | 15% ~06s          
  |+++++++++                                         | 16% ~06s          
  |+++++++++                                         | 17% ~06s          
  |++++++++++                                        | 18% ~06s          
  |++++++++++                                        | 20% ~06s          
  |+++++++++++                                       | 21% ~06s          
  |+++++++++++                                       | 22% ~06s          
  |++++++++++++                                      | 23% ~06s          
  |+++++++++++++                                     | 24% ~06s          
  |+++++++++++++                                     | 25% ~06s          
  |++++++++++++++                                    | 26% ~05s          
  |++++++++++++++                                    | 28% ~05s          
  |+++++++++++++++                                   | 29% ~05s          
  |+++++++++++++++                                   | 30% ~05s          
  |++++++++++++++++                                  | 31% ~05s          
  |+++++++++++++++++                                 | 32% ~05s          
  |+++++++++++++++++                                 | 33% ~05s          
  |++++++++++++++++++                                | 34% ~05s          
  |++++++++++++++++++                                | 36% ~05s          
  |+++++++++++++++++++                               | 37% ~05s          
  |+++++++++++++++++++                               | 38% ~05s          
  |++++++++++++++++++++                              | 39% ~05s          
  |+++++++++++++++++++++                             | 40% ~04s          
  |+++++++++++++++++++++                             | 41% ~04s          
  |++++++++++++++++++++++                            | 43% ~04s          
  |++++++++++++++++++++++                            | 44% ~04s          
  |+++++++++++++++++++++++                           | 45% ~04s          
  |+++++++++++++++++++++++                           | 46% ~04s          
  |++++++++++++++++++++++++                          | 47% ~04s          
  |+++++++++++++++++++++++++                         | 48% ~04s          
  |+++++++++++++++++++++++++                         | 49% ~04s          
  |++++++++++++++++++++++++++                        | 51% ~04s          
  |++++++++++++++++++++++++++                        | 52% ~04s          
  |+++++++++++++++++++++++++++                       | 53% ~04s          
  |++++++++++++++++++++++++++++                      | 54% ~03s          
  |++++++++++++++++++++++++++++                      | 55% ~03s          
  |+++++++++++++++++++++++++++++                     | 56% ~03s          
  |+++++++++++++++++++++++++++++                     | 57% ~03s          
  |++++++++++++++++++++++++++++++                    | 59% ~03s          
  |++++++++++++++++++++++++++++++                    | 60% ~03s          
  |+++++++++++++++++++++++++++++++                   | 61% ~03s          
  |++++++++++++++++++++++++++++++++                  | 62% ~03s          
  |++++++++++++++++++++++++++++++++                  | 63% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 64% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~03s          
  |++++++++++++++++++++++++++++++++++                | 67% ~02s          
  |++++++++++++++++++++++++++++++++++                | 68% ~02s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~02s          
  |++++++++++++++++++++++++++++++++++++              | 70% ~02s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 74% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 78% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 80% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++         | 82% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 94% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=07s  
Calculating cluster 11

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~09s          
  |++                                                | 2 % ~09s          
  |++                                                | 3 % ~09s          
  |+++                                               | 5 % ~09s          
  |+++                                               | 6 % ~08s          
  |++++                                              | 7 % ~08s          
  |+++++                                             | 8 % ~08s          
  |+++++                                             | 9 % ~08s          
  |++++++                                            | 10% ~08s          
  |++++++                                            | 11% ~08s          
  |+++++++                                           | 13% ~08s          
  |+++++++                                           | 14% ~07s          
  |++++++++                                          | 15% ~07s          
  |+++++++++                                         | 16% ~07s          
  |+++++++++                                         | 17% ~07s          
  |++++++++++                                        | 18% ~07s          
  |++++++++++                                        | 20% ~07s          
  |+++++++++++                                       | 21% ~07s          
  |+++++++++++                                       | 22% ~07s          
  |++++++++++++                                      | 23% ~07s          
  |+++++++++++++                                     | 24% ~07s          
  |+++++++++++++                                     | 25% ~06s          
  |++++++++++++++                                    | 26% ~06s          
  |++++++++++++++                                    | 28% ~06s          
  |+++++++++++++++                                   | 29% ~06s          
  |+++++++++++++++                                   | 30% ~06s          
  |++++++++++++++++                                  | 31% ~06s          
  |+++++++++++++++++                                 | 32% ~06s          
  |+++++++++++++++++                                 | 33% ~06s          
  |++++++++++++++++++                                | 34% ~06s          
  |++++++++++++++++++                                | 36% ~06s          
  |+++++++++++++++++++                               | 37% ~05s          
  |+++++++++++++++++++                               | 38% ~05s          
  |++++++++++++++++++++                              | 39% ~05s          
  |+++++++++++++++++++++                             | 40% ~05s          
  |+++++++++++++++++++++                             | 41% ~05s          
  |++++++++++++++++++++++                            | 43% ~05s          
  |++++++++++++++++++++++                            | 44% ~05s          
  |+++++++++++++++++++++++                           | 45% ~05s          
  |+++++++++++++++++++++++                           | 46% ~05s          
  |++++++++++++++++++++++++                          | 47% ~05s          
  |+++++++++++++++++++++++++                         | 48% ~05s          
  |+++++++++++++++++++++++++                         | 49% ~05s          
  |++++++++++++++++++++++++++                        | 51% ~04s          
  |++++++++++++++++++++++++++                        | 52% ~04s          
  |+++++++++++++++++++++++++++                       | 53% ~04s          
  |++++++++++++++++++++++++++++                      | 54% ~04s          
  |++++++++++++++++++++++++++++                      | 55% ~04s          
  |+++++++++++++++++++++++++++++                     | 56% ~04s          
  |+++++++++++++++++++++++++++++                     | 57% ~04s          
  |++++++++++++++++++++++++++++++                    | 59% ~04s          
  |++++++++++++++++++++++++++++++                    | 60% ~04s          
  |+++++++++++++++++++++++++++++++                   | 61% ~03s          
  |++++++++++++++++++++++++++++++++                  | 62% ~03s          
  |++++++++++++++++++++++++++++++++                  | 63% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 64% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~03s          
  |++++++++++++++++++++++++++++++++++                | 67% ~03s          
  |++++++++++++++++++++++++++++++++++                | 68% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~03s          
  |++++++++++++++++++++++++++++++++++++              | 70% ~03s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~03s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 74% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 78% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 80% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 82% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 94% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=09s  
top5 <- ClusterMarkers %>% group_by(cluster) %>% top_n(n=5, wt = avg_log2FC)
DoHeatmap(seu.q, features = top5$gene, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = top5$gene, size = 3, angle = 90,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: MTRNR2L8, MTRNR2L12, SLC1A3, TPT1, RPL37

write.csv(ClusterMarkers,"/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/Neurons1ClusterMarkers11.csv")

Cluster 0 has fewer markers. 2 and 5 have similar up reg markers 3 and 4 also overlap

Look at the cluster markers in cell type libraries for Neurons 2

N1.c6 <- ClusterMarkers %>% filter(cluster == 11 & avg_log2FC > 0)
genes <- N1.c6$gene

N1.c6.Er <- enrichr(genes, databases = db)
Uploading data to Enrichr... Done.
  Querying Allen_Brain_Atlas_up... Done.
  Querying Descartes_Cell_Types_and_Tissue_2021... Done.
  Querying CellMarker_Augmented_2021... Done.
  Querying Azimuth_Cell_Types_2021... Done.
Parsing results... Done.
plotEnrich(N1.c6.Er[[1]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")

plotEnrich(N1.c6.Er[[2]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")

plotEnrich(N1.c6.Er[[3]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")

plotEnrich(N1.c6.Er[[4]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")


N1.Er.genes.1 <- N1.c6.Er[[1]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.1

N1.Er.genes.2 <- N1.c6.Er[[2]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.2

N1.Er.genes.3 <- N1.c6.Er[[3]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.3

N1.Er.genes.4 <- N1.c6.Er[[4]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.4
NA

cluster 0 - astrocyte, radial glia, microglia, striatum - very few genes in these terms cluster 1 - adrenal, thalmus, endothelial, astrocytes, neurons clusters 2 - neural plate, stratum, neurons, NPC, stem, astro,neuroendocrine cluster 3 - brain molecular layer, endothelial, astrocyte embryonic, cluster 4 - DG, striatum CA3, GABAergic neurons cluster 5 - DG, neurons, Glutamatergic neurons cluster 6 - neurons, astrocyte, microglia, GABAneurons cluster 7 - neurons, glut and gaba cluster 8 - astrocyte, endothelial, pericyte cluster 9 - epithelial, embryonic astrocytes, GABA neurons cluster 10 - epithelial cluster 11 - endothelial, immune cells T cells

Expression of markers genes in Neurons2

features <- c("PTPRC","AIF1","ADGRE1", "VIM", "TNC","PTPRZ1","FAM107A","HOPX","LIFR",
              "ITGB5","IL6ST")
DoHeatmap(seu.q, features = features, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = features, size = 3, angle = 90, group.bar.height = 0.02,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: IL6ST, ITGB5, LIFR, HOPX, FAM107A, ADGRE1

DotPlot(seu.q, features = features, group.by = 'RNA_snn_res.0.6')+RotatedAxis()

Label the Neuron2 FACS population

Idents(seu.q) <- 'RNA_snn_res.0.6'
cluster.ids <- c("Neurons1","Neurons2","Neurons3",
                 "Other","DAneurons1","DAneurons2","Neurons4",
                 "DAneurons3","RG","Neurons2","Epithelial","Endothelial")
unique(seu.q$RNA_snn_res.0.6)
 [1] 0  2  1  6  8  3  5  7  4  10 9  11
Levels: 0 1 2 3 4 5 6 7 8 9 10 11
names(cluster.ids) <- levels(seu.q)
seu.q <- RenameIdents(seu.q, cluster.ids)
seu.q$number.groups <- Idents(seu.q)

DimPlot(seu.q, reduction = "umap", label = TRUE, group.by = 'number.groups', repel = TRUE)

Proportions of cell types

Find markers in pairs to go back and classify the subgroups. Will need to return to this for Neurons1 FACS

Neurons 5 and Neurons2 had similar markers and were merged Subset again


top5 <- neuron.sub.markers %>% group_by(cluster) %>% top_n(n=5, wt = avg_log2FC)
DoHeatmap(neuron.sub, features = top5$gene, size=3, angle =90, group.bar.height = 0.02)

DotPlot(neuron.sub, features = top5$gene) + RotatedAxis()
Warning: Scaling data with a low number of groups may produce misleading results

Use subgrouping and find cluster markers to look at neuronal subtypes.


top5 <- neuron.sub.markers %>% group_by(cluster) %>% top_n(n=5, wt = avg_log2FC)
DoHeatmap(neuron.sub, features = top5$gene, size=3, angle =90, group.bar.height = 0.02)

DotPlot(neuron.sub, features = top5$gene) + RotatedAxis()
Warning: Scaling data with a low number of groups may produce misleading results

Name the Neurons2 FACS population with the Neuron subtype latter.


Idents(seu.q) <- 'RNA_snn_res.0.6'
cluster.ids <- c("Neurons-MSX1","Neurons-LY6H","Neurons-ASCL1",
                 "Other","DAneurons-CYP1B1","DAneurons-ASCL1","Neurons-GK5",
                 "DAneurons-NEUROD1","RG","Neurons-LY6H","Epithelial","Endothelial")

unique(seu.q$RNA_snn_res.0.6)
 [1] 0  2  1  6  8  3  5  7  4  10 9  11
Levels: 0 1 2 3 4 5 6 7 8 9 10 11
names(cluster.ids) <- levels(seu.q)
seu.q <- RenameIdents(seu.q, cluster.ids)
seu.q$cellsubgroups <- Idents(seu.q)

DimPlot(seu.q, reduction = "umap", label = TRUE, group.by = 'cellsubgroups', repel = TRUE)

NA
NA

# save the Neurons2 with labels

saveRDS(seu.q, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/objs/Neurons2LabelsSeu30092022.RDS")

FACS population Glia1 (should be astrocytes)

seu.ft
An object of class Seurat 
33541 features across 47295 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO

saveRDS(seu.ft, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/objs/Glia1AstroSeu01102022.RDS")

Doublet finder


suppressMessages(require(DoubletFinder))

# filtering out MALAT1 and mitochondrial genes

seu.ft <- seu.ft[!grepl("MALAT1", rownames(seu.ft)), ]
seu.ft <- seu.ft[!grepl("^MT-", rownames(seu.ft)), ]

# like in the tutorial I'm following MALAT1 is the top most expressed gene.  The top genes are a lot of MT and Ribosomal genes

seu.ft[["percent.rb"]] <- PercentageFeatureSet(seu.ft, pattern = "^RP")

# down sample there are too many cells to run doublet finder
seu.sub <- subset(seu.ft, downsample = 20000)

seu.d = NormalizeData(seu.sub)
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
seu.d = FindVariableFeatures(seu.d, verbose = F)
seu.d = ScaleData(seu.d, vars.to.regress = c("nFeature_RNA", "percent.mt"),
    verbose = F)
seu.d = RunPCA(seu.d, verbose = F, npcs = 15)
seu.d = RunUMAP(seu.d, dims = 1:10, verbose = F)

nExp <- round(ncol(seu.d) * 0.15)  # expect more doublets because there is a lot more cells
seu.d <- doubletFinder_v3(seu.d, pN = 0.25, pK = 0.09, nExp = nExp, PCs = 1:10)
Loading required package: fields
Loading required package: spam
Spam version 2.9-1 (2022-08-07) is loaded.
Type 'help( Spam)' or 'demo( spam)' for a short introduction 
and overview of this package.
Help for individual functions is also obtained by adding the
suffix '.spam' to the function name, e.g. 'help( chol.spam)'.

Attaching package: ‘spam’

The following object is masked from ‘package:Matrix’:

    det

The following objects are masked from ‘package:base’:

    backsolve, forwardsolve

Loading required package: viridis
Loading required package: viridisLite

Try help(fields) to get started.
Loading required package: KernSmooth
KernSmooth 2.23 loaded
Copyright M. P. Wand 1997-2009
[1] "Creating 6667 artificial doublets..."
[1] "Creating Seurat object..."
[1] "Normalizing Seurat object..."
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "Finding variable genes..."
Calculating gene variances
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating feature variances of standardized and clipped values
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "Scaling data..."
Centering and scaling data matrix

  |                                                                               
  |                                                                         |   0%
  |                                                                               
  |====================================                                     |  50%
  |                                                                               
  |=========================================================================| 100%
[1] "Running PCA..."
[1] "Calculating PC distance matrix..."
[1] "Computing pANN..."
[1] "Classifying doublets.."
# the memory limit is reached here - I could run on compute canada
# For now I'll downsample
# this works

# name of the DF prediction can change, so extract the correct column name.
DF.name = colnames(seu.d@meta.data)[grepl("DF.classification", colnames(seu.d@meta.data))]


cowplot::plot_grid(ncol = 2, DimPlot(seu.d, group.by = "orig.ident") + NoAxes(),
    DimPlot(seu.d, group.by = DF.name) + NoAxes())


VlnPlot(seu.d, features = "nFeature_RNA", group.by = DF.name, pt.size = 0.1)

Remove the doublet cells

dim(seu.d)
[1] 33524 17000
dim(seu.sub)
[1] 33524 20000

Repeat workflow with doublet removed data and find clusters for

seu <- NormalizeData(seu.d, normalization.method = "LogNormalize", scale.factor = 10000)
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
seu <- FindVariableFeatures(seu, selection.method = "vst", nfeatures = 2000)
Calculating gene variances
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating feature variances of standardized and clipped values
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
seu <- ScaleData(seu)
Centering and scaling data matrix

  |                                                                               
  |                                                                         |   0%
  |                                                                               
  |====================================                                     |  50%
  |                                                                               
  |=========================================================================| 100%
seu <- RunPCA(seu)
PC_ 1 
Positive:  TMSB10, COL3A1, LGALS1, IGFBP4, PPIB, DCN, COL1A1, CALD1, S100A6, COL1A2 
       TIMP1, COL6A3, S100A4, NDUFA4L2, LUM, IFITM3, VIM, S100A11, VCAN, COL6A1 
       SELENOM, RPL10, RPL18A, APOE, RACK1, MDK, LGALS3, COL6A2, SERPINF1, RPS23 
Negative:  PMCH, CLU, AF131216.1, YJEFN3, AC068389.1, AC005014.2, MMP21, PTPRZ1, PLEK2, AC096667.1 
       S100A9, PITX1, AC010524.1, INA, DDI1, GPHA2, AC240565.1, IMPG2, AC243829.1, AC098934.4 
       ADAMTS20, DMRT3, AC022784.1, AC034198.2, MFNG, STPG3-AS1, PTPRH, AC092634.5, IGKV1-6, AC010422.2 
PC_ 2 
Positive:  COL3A1, COL1A2, COL1A1, DCN, VCAN, LUM, COL6A3, IGFBP4, S100A4, COL6A1 
       NDUFA4L2, APOD, COL4A1, OGN, COL6A2, APOE, S100A6, MFAP4, COL4A2, EDNRA 
       PRRX1, TMSB10, COL5A2, TNFAIP6, THY1, FN1, COL5A1, IFITM3, CYTL1, CFH 
Negative:  S100B, IGFBP2, TPBG, CRYAB, LY6H, HPD, KRT18, GSTP1, KRT8, METRN 
       SOX2, ARL4C, ITM2C, PTPRZ1, SERTM1, HES1, DPCD, CA2, PLTP, ABHD14A 
       PAPPA2, MGST1, CBLN1, PSAT1, BEX1, ESM1, WFIKKN2, HIST1H4C, EFEMP1, LIX1 
PC_ 3 
Positive:  PTGDS, SERPINF1, ECEL1, PRSS56, APOC1, BST2, ID1, FABP5, CITED4, RBP1 
       ASS1, TMEM176A, CDKN1C, TMEM176B, KDR, DCN, EMX2, ASCL1, APOE, SOD3 
       CCNG2, RPL39, DES, EMX2OS, WIF1, ADRA2C, RPL10, RPL7A, RPL32, RAMP1 
Negative:  SCG2, PTPRZ1, ESM1, COL1A1, COL1A2, TFPI2, GABBR2, VCAN, FN1, OGN 
       ABCA8, GNG11, LUM, NTRK2, COL3A1, S100A10, SOX2, RFX4, COL4A1, COL6A1 
       PTN, ITPR2, CBLN1, APOD, SPARCL1, NR2F1, LY6H, TNFAIP6, SLC7A11, ANXA1 
PC_ 4 
Positive:  CXCL14, IGFBP2, PCP4, OGN, CA2, CP, WFIKKN2, IGFBP7, IGF1, PLAC9 
       SPINT2, FHIT, GPNMB, KRT18, EFEMP1, DKK3, COL1A2, KRT8, FOLR1, VCAN 
       DMKN, CRABP1, TPBG, SERF2, ENPP2, COL1A1, PRRX1, CRABP2, TNFAIP6, KCNJ13 
Negative:  APOE, PTN, DLK1, SCG2, APOC1, DCN, FABP5, GDF10, PTPRZ1, CLU 
       ESM1, KDR, PRSS56, PEG10, TFPI2, SPARCL1, RDH10, RFX4, GNG11, SLC7A2 
       IFITM1, BST2, GABBR2, ABCA8, COL23A1, ITM2C, CITED4, KCNQ1OT1, CCNG2, SYNDIG1 
PC_ 5 
Positive:  KCNQ1OT1, NEAT1, DSP, CYP1B1, CP, KHDRBS2, SLC5A3, SLC4A10, AKAP12, LINC00473 
       PTP4A1, HMGCS1, PAPPA2, IGFBP3, WFIKKN2, AC092683.1, HTR2C, IGFBP5, WIF1, SLCO1C1 
       UACA, TRPM3, LAMB1, KCNJ13, SPARCL1, MDM2, RAB3IP, KDR, CA2, SV2C 
Negative:  RPS12, RPL10, RPL39, RPS23, RPL32, FTL, RPS28, RPL26, RPL12, RPS3 
       RPL7A, RPL8, RPS4X, RPL18A, GSTP1, IFI27L2, VIM, FTH1, S100A10, RACK1 
       IFI27, GAPDH, SERF2, GNG11, TXN, LY6H, HIST1H4C, LGALS1, TFPI2, RPS4Y1 
seu <- RunUMAP(seu, reduction = "pca", n.neighbors = 43, dims = 1:30)
12:20:48 UMAP embedding parameters a = 0.9922 b = 1.112
12:20:48 Read 20000 rows and found 30 numeric columns
12:20:48 Using Annoy for neighbor search, n_neighbors = 43
12:20:48 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
12:20:49 Writing NN index file to temp file /var/folders/k4/khtkczkd5tn732ftjpwgtr240000gn/T//RtmpOCo8CT/file74b220cfcf06
12:20:49 Searching Annoy index using 1 thread, search_k = 4300
12:20:55 Annoy recall = 100%
12:20:56 Commencing smooth kNN distance calibration using 1 thread with target n_neighbors = 43
12:20:57 Initializing from normalized Laplacian + noise (using irlba)
12:20:58 Commencing optimization for 200 epochs, with 1288572 positive edges
Using method 'umap'
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
12:21:12 Optimization finished
DimPlot(seu, reduction = "umap")


seu.q <- FindNeighbors(seu, dims = 1:25, k.param = 43)
Computing nearest neighbor graph
Computing SNN
seu.q <- FindClusters(seu.q, resolution = c(0,0.2,0.4,0.6))
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 20000
Number of edges: 760620

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 1.0000
Number of communities: 1
Elapsed time: 3 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 20000
Number of edges: 760620

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8636
Number of communities: 6
Elapsed time: 2 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 20000
Number of edges: 760620

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8123
Number of communities: 10
Elapsed time: 3 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 20000
Number of edges: 760620

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7734
Number of communities: 11
Elapsed time: 4 seconds
seu.q <- FindClusters(seu.q, resolution = c(0,0.05,0.1,0.8))
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 20000
Number of edges: 760620

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 1.0000
Number of communities: 1
Elapsed time: 3 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 20000
Number of edges: 760620

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.9522
Number of communities: 3
Elapsed time: 3 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 20000
Number of edges: 760620

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.9166
Number of communities: 4
Elapsed time: 3 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 20000
Number of edges: 760620

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7376
Number of communities: 13
Elapsed time: 4 seconds
library(clustree)
Loading required package: ggraph

Attaching package: ‘ggraph’

The following object is masked from ‘package:sp’:

    geometry
clustree(seu.q)

DimPlot(seu.q, reduction = "umap", group.by = 'RNA_snn_res.0.05')

DimPlot(seu.q, reduction = "umap", group.by = 'RNA_snn_res.0.1')

DimPlot(seu.q, reduction = "umap", group.by = 'RNA_snn_res.0.2')

DimPlot(seu.q, reduction = "umap", group.by = 'RNA_snn_res.0.4')

DimPlot(seu.q, reduction = "umap", group.by = 'RNA_snn_res.0.6')

DimPlot(seu.q, reduction = "umap", group.by = 'RNA_snn_res.0.8')

NA
NA
NA
NA

Look at some expression markers in a feature plot

# genes reported up in Astrocytes
FeaturePlot(seu.q, features = c("GFAP","S100B","AQP4","SLC1A3","GJA1",
                                "APOE","TEAD1","GSTA4","SOX9",
                                "VIM","HMG20A","ALDH1L1"))

# almost no GFAP expression and lots of S100B everywhere

Predict cell types



# SNCA and control midbrain organoids 165 days in culture
MBO <- readRDS("/Users/rhalenathomas/Documents/Data/scRNAseq/AST23_BrainComm/MBOclusters_names29072021.rds")

# Midbrain  AIW002 120 days in culture
AIWMBO <- readRDS("/Users/rhalenathomas/Documents/Data/scRNAseq/AIWtrio120days/MOintegratedClusterK123res0.8.names_nov16_2021")

# Midbrain AIW002 60 days in culture

AIW60 <- readRDS("/Users/rhalenathomas/Documents/Data/scRNAseq/AIWtrio60days/AWI002ParkinKOPinkKO60days_labels_14052022.rds")


#first predict with the MBO data
Idents(MBO) <- "cluster_labels"
DefaultAssay(MBO) <- "RNA"

# find the reference anchors
print("finding reference anchors")
[1] "finding reference anchors"
anchors <- FindTransferAnchors(reference = MBO ,query = seu.q, dims = 1:25)
Performing PCA on the provided reference using 1997 features as input.
Projecting cell embeddings
Finding neighborhoods
Finding anchors
    Found 814 anchors
Filtering anchors
    Retained 219 anchors
as(<ngCMatrix>, "dgCMatrix") is deprecated since Matrix 1.5-0; do as(., "dMatrix") instead
print("getting predictions")
[1] "getting predictions"
predictions <- TransferData(anchorset = anchors, refdata = MBO$cluster_labels)
Finding integration vectors
Finding integration vector weights
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Predicting cell labels
seu.q <- AddMetaData(seu.q, metadata = predictions)
print(table(seu.q$predicted.id))

      Epithelial        Neurons-e Oligodendrocytes             RGd1 
             587              451            11247             7689 
            RGd2 
              26 
Idents(seu.q) <- 'predicted.id'
# add new dataslot for MBO predicted ID to make the next prediction
seu.q$MBOAST23.pred <- Idents(seu.q)
DimPlot(seu.q, group.by = 'MBOAST23.pred', label = TRUE)

 
## check the proportion of cell types predicted in each cluster
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.8, seu.q$MBOAST23.pred))
t.lables$Freq <- as.double(t.lables$Freq)

# try bar chart
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity")


# clusters don't break up by the predicted cell types

############ another predictions now using the AIW organoids

Idents(AIWMBO) <- "res08names"
DefaultAssay(AIWMBO) <- "RNA"

anchors <- FindTransferAnchors(reference = AIWMBO ,query = seu.q, dims = 1:25)
Performing PCA on the provided reference using 2000 features as input.
Projecting cell embeddings
Finding neighborhoods
Finding anchors
    Found 3639 anchors
Filtering anchors
    Retained 1713 anchors
print("getting predictions")
[1] "getting predictions"
predictions <- TransferData(anchorset = anchors, refdata = AIWMBO$res08names)
Finding integration vectors
Finding integration vector weights
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Predicting cell labels
seu.q <- AddMetaData(seu.q, metadata = predictions)
print(table(seu.q$predicted.id))

       epithelial        Neurons_DA Neurons_early_inh             oligo 
               60                 1              5622               110 
              OPC               RGa              RGd1              RGd3 
              241             13950                 3                13 
Idents(seu.q) <- 'predicted.id'
# add new dataslot for MBO predicted ID to make the next prediction
seu.q$MBOAIW.pred <- Idents(seu.q)
DimPlot(seu.q, group.by = 'MBOAIW.pred', label = TRUE)

 
## check the proportion of cell types predicted in each cluster
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.8, seu.q$MBOAIW.pred))
t.lables$Freq <- as.double(t.lables$Freq)

# try bar chart
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity")


# the predicted cell types make more sense from the AIW002 organoid
# now predict with the AIW002 60 days organoid

Idents(AIW60) <- "cluster.ids"
DefaultAssay(AIW60) <- "RNA"

anchors <- FindTransferAnchors(reference = AIW60, query = seu.q, dims = 1:25)
Performing PCA on the provided reference using 1999 features as input.
Projecting cell embeddings
Finding neighborhoods
Finding anchors
    Found 2402 anchors
Filtering anchors
    Retained 645 anchors
print("getting predictions")
[1] "getting predictions"
predictions <- TransferData(anchorset = anchors, refdata = AIW60$cluster.ids) 
Finding integration vectors
Finding integration vector weights
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Predicting cell labels
seu.q <- AddMetaData(seu.q, metadata = predictions)
print(table(seu.q$predicted.id))

                  Astrocytes Dopaminergic Neurons early 1 
                           1                           31 
           Neural Epithelial            Neural Precursors 
                          12                         7145 
               Radial Glia 1                Radial Glia 2 
                       12806                            5 
Idents(seu.q) <- 'predicted.id'
# add new dataslot for MBO predicted ID to make the next prediction
seu.q$AIW60.pred <- Idents(seu.q)
DimPlot(seu.q, group.by = 'AIW60.pred', label = TRUE)

 
## check the proportion of cell types predicted in each cluster
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.8, seu.q$AIW60.pred))
t.lables$Freq <- as.double(t.lables$Freq)

# try bar chart
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity")


# save ojbect with predicitons
saveRDS(seu.q, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/objs/Glia1PredictionsSeu01102022.RDS")

Look at the reference objects


# triplication
DimPlot(MBO)

# AIW 60 days
DimPlot(AIW60)

# AIW 120 days
DimPlot(AIWMBO)

NA
NA

Look more at the predictions


# AIW002 120 days predictions
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.2, seu.q$MBOAIW.pred))
t.lables$Freq <- as.double(t.lables$Freq)
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity") + RotatedAxis() 

top.pred.celltype.AIW120 <- as.data.frame(t.lables  %>% group_by(Var1)  %>% top_n(2, Freq))
df.top.aiw120 <- top.pred.celltype.AIW120[order(top.pred.celltype.AIW120$Var1,-top.pred.celltype.AIW120$Freq),]
row.names(df.top.aiw120) <- NULL
df.top.aiw120$I <- row.names(df.top.aiw120)

# AIW002 60 days predictions
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.2, seu.q$AIW60.pred))
t.lables$Freq <- as.double(t.lables$Freq)
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity") + RotatedAxis() 

top.pred.celltype.AIW60 <-as.data.frame(t.lables  %>% group_by(Var1)  %>% top_n(2, Freq))
df.top.aiw60 <- top.pred.celltype.AIW60[order(top.pred.celltype.AIW60$Var1,-top.pred.celltype.AIW60$Freq),]
row.names(df.top.aiw60) <- NULL
df.top.aiw60$I <- row.names(df.top.aiw60)


# AST23 165 days predictions
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.2, seu.q$MBOAST23.pred))
t.lables$Freq <- as.double(t.lables$Freq)
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity") + RotatedAxis() 

top.pred.celltype.AST23 <- as.data.frame(t.lables  %>% group_by(Var1)  %>% top_n(2, Freq))
df.top.AST23 <- top.pred.celltype.AST23[order(top.pred.celltype.AST23$Var1,-top.pred.celltype.AST23$Freq),]
row.names(df.top.AST23) <- NULL
df.top.AST23$I <- row.names(df.top.AST23)

pred.table <- merge(df.top.AST23, df.top.aiw60, by = 'I', all = TRUE)
pred.table <- merge(pred.table, df.top.aiw120, by = 'I')
pred.table
NA

These predictions are not good. There are several astrocyte markers by expression levels. Everything is predicted as Radial glia or oligo dendrocytes

Try to predict with the astrocyte Kamath data

Look at cluster markers

top5 <- ClusterMarkers %>% group_by(cluster) %>% top_n(n=5, wt = avg_log2FC)
DoHeatmap(seu.q, features = top5$gene, size=3, angle =90, group.bar.height = 0.02)
Warning in DoHeatmap(seu.q, features = top5$gene, size = 3, angle = 90,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: LRRC75A, SNHG25

Check cell type markers with EnrichR

N1.c0 <- ClusterMarkers %>% filter(cluster == 5 & avg_log2FC > 0)
genes <- N1.c0$gene

N1.c0.Er <- enrichr(genes, databases = db)
Uploading data to Enrichr... Done.
  Querying Allen_Brain_Atlas_up... Done.
  Querying Descartes_Cell_Types_and_Tissue_2021... Done.
  Querying CellMarker_Augmented_2021... Done.
  Querying Azimuth_Cell_Types_2021... Done.
Parsing results... Done.
plotEnrich(N1.c0.Er[[1]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")

plotEnrich(N1.c0.Er[[2]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")

plotEnrich(N1.c0.Er[[3]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")

plotEnrich(N1.c0.Er[[4]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")


N1.Er.genes.1 <- N1.c0.Er[[1]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.1

N1.Er.genes.2 <- N1.c0.Er[[2]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.2

N1.Er.genes.3 <- N1.c0.Er[[3]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.3


N1.Er.genes.4 <- N1.c0.Er[[4]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.4



# cluster 0 - Cell type marker library - Brain astrocyte top hit and embryonic astrocytes
# gene list in term: brain astrocyte    EFEMP1;NFIA;LIX1;PSAP;KIF21A;S100B;CRYAB;DKK3
# embryo astrocytes SOX2;BEX1;HMGCS1;PTPRZ1;LIX1;S100B;DKK3;ITM2C

# cluster 1 - stem cell pericyte (brain), stelate, astrocyte

# cluster 2 - hypothalmus, endothelial cells, macrophage
# endothelial CSTB;PRELID1;MT1X;CRIP2;RHOC;TMEM141;MT2A;RPS28;CCDC85B;EIF3I;RBP1;ID1;C4ORF3;ID3;PCBD1;MSX1;PPIC

# cluster 3 - smooth muscle cells

# cluster 4 - NK cells, fibroblasts
# NK cells ITGB1;RAB5C;GSTP1;PDCD5;EEF1B2;TGOLN2;SDCBP;MT2A;LDHA;SNRPD2;YWHAQ;ZNF326;TMSB10;CCDC50
# fibroblasts   COL3A1;CALD1;COL6A3

# cluster 5 - endothelial cells, NK cells, CD8+

# cluster 6 - stromal cells eurythroblasts, none-neuronal, oligo

# reran and now there are only 5 clusters
# repeat checking

Cluster 0 - astrocytes Cluster 1 - pericyte astrocyte (weak still) Cluster 2 - endothelial Cluster 3 - smooth muscle Cluster 4 - NK/fibroblast Cluster 5 - endothelial Cluster 6 - non- neuronal


VlnPlot(seu.q, features = c("CD44","ITGB1","S100B"), group.by = 'orig.ident')

VlnPlot(seu.ft, features = c("CD44","ITGB1","S100B"), group.by = 'orig.ident')

Check expression of known markers

features <- c("PTPRC","AIF1","ADGRE1", "VIM", "TNC","PTPRZ1","FAM107A","HOPX","LIFR",
              "ITGB5","IL6ST")
DoHeatmap(seu.q, features = features, size=3, angle =90, group.bar.height = 0.02)
Warning in DoHeatmap(seu.q, features = features, size = 3, angle = 90, group.bar.height = 0.02) :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: IL6ST, ITGB5, LIFR, ADGRE1, AIF1

DotPlot(seu.q, features = features)+RotatedAxis()

No TH expression

clusters 5 VIM highest, S100 B Cluster 4 Cluster 3 has some cells with high OTX2, NES indicates NPC/Precursors Cluster 2 has some SOX2 and PAX6 indicates NPC, VAMP2 indicating neurons, S100B highest and most - indicates astrocytes, also MBP indicates oligos Cluster 1 Cluster 0

Lable the clusters


Idents(seu.q) <- 'RNA_snn_res.0.2'

#seu.q <- BuildClusterTree(seu.q, reorder = TRUE, reorder.numeric = TRUE)
unique(seu.q$RNA_snn_res.0.2)
[1] 0 1 4 3 2 5
Levels: 0 1 2 3 4 5
cluster.ids <- c("Astrocytes1","Astrocytes2","Precursors","RG1","RG2","Endothelial")

names(cluster.ids) <- levels(seu.q)
seu.q <- RenameIdents(seu.q, cluster.ids)
seu.q$subgroups <- Idents(seu.q)

#DimPlot(seu.q, group.by = 'RNA_snn_res.0.2', label = TRUE)
DimPlot(seu.q, reduction = "umap", label = TRUE, group.by = 'subgroups', repel = TRUE)


# something weird is going on in the order

#saveRDS(seu.q, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/objs/Glia1LabledSeu301102022.RDS")

Compare the Astrocyte groups and get some markers for sub groups

npc.markers <- npc.markers %>% filter(avg_log2FC > 0)
dim(npc.markers)
[1] 292   5

Add subtype gene ids

Proportions of cells types

Quick check the Glial2


seu.ft <- subset(seu, subset = nFeature_RNA > 250 & nCount_RNA > 250 & nCount_RNA < 10000) 
seu.ft
An object of class Seurat 
33541 features across 7553 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO
VlnPlot(seu.ft, pt.size = 0.10, features = c("nFeature_RNA"), y.max = 2000)
Warning: Removed 1310 rows containing non-finite values (stat_ydensity).
Warning: Removed 1310 rows containing missing values (geom_point).


VlnPlot(seu.ft.glia, features = c("CD44","S100B","ITGB1"))

VlnPlot(seu.ft, features = c("CD44","S100B","ITGB1"), group.by = 'orig.ident')

Levels seem similar in Glia1 and Glia2

Remove doublets and start to process Glia 2


suppressMessages(require(DoubletFinder))

# filtering out MALAT1 and mitochondrial genes

seu.ft <- seu.ft[!grepl("MALAT1", rownames(seu.ft)), ]
seu.ft <- seu.ft[!grepl("^MT-", rownames(seu.ft)), ]

# like in the tutorial I'm following MALAT1 is the top most expressed gene.  The top genes are a lot of MT and Ribosomal genes

seu.ft[["percent.rb"]] <- PercentageFeatureSet(seu.ft, pattern = "^RP")

seu.d = NormalizeData(seu.ft)
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
seu.d = FindVariableFeatures(seu.d, verbose = F)
seu.d = ScaleData(seu.d, vars.to.regress = c("nFeature_RNA", "percent.mt"),
    verbose = F)
seu.d = RunPCA(seu.d, verbose = F, npcs = 15)
seu.d = RunUMAP(seu.d, dims = 1:10, verbose = F)

nExp <- round(ncol(seu.d) * 0.08)  # expect more doublets because there is a lot more cells
seu.d <- doubletFinder_v3(seu.d, pN = 0.25, pK = 0.09, nExp = nExp, PCs = 1:10)
[1] "Creating 2518 artificial doublets..."
[1] "Creating Seurat object..."
[1] "Normalizing Seurat object..."
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "Finding variable genes..."
Calculating gene variances
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating feature variances of standardized and clipped values
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "Scaling data..."
Centering and scaling data matrix

  |                                                                                 
  |                                                                           |   0%
  |                                                                                 
  |======================================                                     |  50%
  |                                                                                 
  |===========================================================================| 100%
[1] "Running PCA..."
[1] "Calculating PC distance matrix..."
[1] "Computing pANN..."
[1] "Classifying doublets.."
# the memory limit is reached here - I could run on compute canada
# For now I'll downsample
# this works

# name of the DF prediction can change, so extract the correct column name.
DF.name = colnames(seu.d@meta.data)[grepl("DF.classification", colnames(seu.d@meta.data))]


cowplot::plot_grid(ncol = 2, DimPlot(seu.d, group.by = "orig.ident") + NoAxes(),
    DimPlot(seu.d, group.by = DF.name) + NoAxes())


VlnPlot(seu.d, features = "nFeature_RNA", group.by = DF.name, pt.size = 0.1)


seu.d <- seu.d[, seu.d@meta.data[, DF.name]== "Singlet"]
dim(seu.d)
[1] 33524  6949
dim(seu.ft)
[1] 33524  7553

Cluster

Predict cell types


#first predict with the MBO data
Idents(MBO) <- "cluster_labels"
DefaultAssay(MBO) <- "RNA"

# find the reference anchors
print("finding reference anchors")
[1] "finding reference anchors"
anchors <- FindTransferAnchors(reference = MBO ,query = seu.q, dims = 1:25)
Performing PCA on the provided reference using 1997 features as input.
Projecting cell embeddings
Finding neighborhoods
Finding anchors
    Found 1209 anchors
Filtering anchors
    Retained 559 anchors
print("getting predictions")
[1] "getting predictions"
predictions <- TransferData(anchorset = anchors, refdata = MBO$cluster_labels)
Finding integration vectors
Finding integration vector weights
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Predicting cell labels
seu.q <- AddMetaData(seu.q, metadata = predictions)

Idents(seu.q) <- 'predicted.id'
# add new dataslot for MBO predicted ID to make the next prediction
seu.q$MBOAST23.pred <- Idents(seu.q)
DimPlot(seu.q, group.by = 'MBOAST23.pred', label = TRUE)


# see how accurate the predictions are
seu.q$predicted.id <- ifelse(seu.q$prediction.score.max > 0.95, seu.q$predicted.id, "None")

Idents(seu.q) <- 'predicted.id'
seu.q$MBOAST23.thresh <- Idents(seu.q)
DimPlot(seu.q, group.by = 'predicted.id', label = TRUE)

table(seu.q$MBOAST23.pred)

             RGd1  Oligodendrocytes         Neurons-e Neural Precursors        Neurons-DA 
             1176              4567               976               117               105 
       Epithelial 
                8 
table(seu.q$MBOAST23.thresh)

             RGd1              None  Oligodendrocytes         Neurons-e        Neurons-DA 
              254              5203              1446                33                10 
Neural Precursors 
                3 
 
## check the proportion of cell types predicted in each cluster
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.4, seu.q$MBOAST23.pred))
t.lables$Freq <- as.double(t.lables$Freq)

# try bar chart
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity")


# clusters don't break up by the predicted cell types

############ another predictions now using the AIW organoids

Idents(AIWMBO) <- "res08names"
DefaultAssay(AIWMBO) <- "RNA"

anchors <- FindTransferAnchors(reference = AIWMBO ,query = seu.q, dims = 1:25)
Performing PCA on the provided reference using 2000 features as input.
Projecting cell embeddings
Finding neighborhoods
Finding anchors
    Found 3816 anchors
Filtering anchors
    Retained 2248 anchors
print("getting predictions")
[1] "getting predictions"
predictions <- TransferData(anchorset = anchors, refdata = AIWMBO$res08names)
Finding integration vectors
Finding integration vector weights
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Predicting cell labels
seu.q <- AddMetaData(seu.q, metadata = predictions)
print(table(seu.q$predicted.id))

       epithelial        Neurons_DA Neurons_early_inh             oligo               OPC 
               31               217              4407                76               119 
              RGa              RGd3 
             2074                25 
Idents(seu.q) <- 'predicted.id'
# add new dataslot for MBO predicted ID to make the next prediction
seu.q$AIW120.pred <- Idents(seu.q)
DimPlot(seu.q, group.by = 'AIW120.pred', label = TRUE)

 
## check the proportion of cell types predicted in each cluster
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.4, seu.q$MBOAIW.pred))
t.lables$Freq <- as.double(t.lables$Freq)
# try bar chart
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity")


# see how accurate the predictions are
seu.q$predicted.id <- ifelse(seu.q$prediction.score.max > 0.95, seu.q$predicted.id, "None")

Idents(seu.q) <- 'predicted.id'
seu.q$AIW120.thresh <- Idents(seu.q)
DimPlot(seu.q, group.by = 'AIW120.thresh', label = TRUE)

table(seu.q$AIW120.pred)

              RGa Neurons_early_inh        Neurons_DA             oligo               OPC 
             2074              4407               217                76               119 
             RGd3        epithelial 
               25                31 
table(seu.q$AIW120.thresh)

              RGa Neurons_early_inh              None        Neurons_DA               OPC 
             1052              2735              2861               177               110 
             RGd3        epithelial 
               10                 4 
# the predicted cell types make more sense from the AIW002 organoid
# now predict with the AIW002 60 days organoid

Idents(AIW60) <- "cluster.ids"
DefaultAssay(AIW60) <- "RNA"

anchors <- FindTransferAnchors(reference = AIW60, query = seu.q, dims = 1:25)
Performing PCA on the provided reference using 1999 features as input.
Projecting cell embeddings
Finding neighborhoods
Finding anchors
    Found 3345 anchors
Filtering anchors
    Retained 1582 anchors
print("getting predictions")
[1] "getting predictions"
predictions <- TransferData(anchorset = anchors, refdata = AIW60$cluster.ids) 
Finding integration vectors
Finding integration vector weights
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Predicting cell labels
seu.q <- AddMetaData(seu.q, metadata = predictions)
print(table(seu.q$predicted.id))

Dopaminergic Neurons early 1            Neural Epithelial            Neural Precursors 
                         218                           25                         4973 
               Radial Glia 1 
                        1733 
Idents(seu.q) <- 'predicted.id'
# add new dataslot for MBO predicted ID to make the next prediction
seu.q$AIW60.pred <- Idents(seu.q)
DimPlot(seu.q, group.by = 'AIW60.pred', label = TRUE)

 
## check the proportion of cell types predicted in each cluster
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.4, seu.q$AIW60.pred))
t.lables$Freq <- as.double(t.lables$Freq)

# try bar chart
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity")


# see how accurate the predictions are
seu.q$predicted.id <- ifelse(seu.q$prediction.score.max > 0.95, seu.q$predicted.id, "None")

Idents(seu.q) <- 'predicted.id'
seu.q$AIW60.thresh <- Idents(seu.q)
DimPlot(seu.q, group.by = 'AIW60.thresh', label = TRUE)

table(seu.q$AIW60.pred)

               Radial Glia 1            Neural Precursors Dopaminergic Neurons early 1 
                        1733                         4973                          218 
           Neural Epithelial 
                          25 
table(seu.q$AIW60.thresh)

               Radial Glia 1            Neural Precursors                         None 
                         972                         3138                         2740 
Dopaminergic Neurons early 1 
                          99 
# save with predictions so far
saveRDS(seu.q, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/objs/Glia2LabledSeu03102022.RDS")

See how many cells are predicted as astrocytes with the threshold

DAsubtypes <- readRDS("/Users/rhalenathomas/Documents/Data/scRNAseq/Macosko_Data/DAsubgroups_processed.Rds")

Idents(astro.ref) <- "Cell_Subtype"
DefaultAssay(astro.ref) <- "RNA"

# find the reference anchors
print("finding reference anchors")
[1] "finding reference anchors"
anchors <- FindTransferAnchors(reference = DAsubtypes ,query = seu.q, dims = 1:20)
Error: vector memory exhausted (limit reached?)

Do these get labelled as DA neurons too???

seu.q <- readRDS("/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/objs/Glia2LabledSeu03102022.RDS")
Warning message:
R graphics engine version 15 is not supported by this version of RStudio. The Plots tab will be disabled until a newer version of RStudio is installed. 

seu.q$predicted.id <- ifelse(seu.q$prediction.score.max > 0.95, seu.q$predicted.id, "none")

Idents(seu.q) <- 'predicted.id'
seu.q$da.pred.thresh <- Idents(seu.q)
DimPlot(seu.q, group.by = 'da.pred.thresh', label = TRUE)
table(seu.q$da.pred.thresh)

      none CALB1_RBP4 
      6213        736 

Compare predictions - make a predictions table


# AIW002 120 days predictions - take the thresholded options
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.2, seu.q$AIW120.thresh))
t.lables$Freq <- as.double(t.lables$Freq)
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity") + RotatedAxis() 

top.pred.celltype.AIW120 <- as.data.frame(t.lables  %>% group_by(Var1)  %>% top_n(2, Freq))
df.top.aiw120 <- top.pred.celltype.AIW120[order(top.pred.celltype.AIW120$Var1,-top.pred.celltype.AIW120$Freq),]
row.names(df.top.aiw120) <- NULL
df.top.aiw120$I <- row.names(df.top.aiw120)

# AIW002 60 days predictions
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.2, seu.q$AIW60.thresh))
t.lables$Freq <- as.double(t.lables$Freq)
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity") + RotatedAxis() 
*** recursive gc invocation
*** recursive gc invocation
*** recursive gc invocation
*** recursive gc invocation
*** recursive gc invocation
*** recursive gc invocation
*** recursive gc invocation
*** recursive gc invocation

top.pred.celltype.AIW60 <-as.data.frame(t.lables  %>% group_by(Var1)  %>% top_n(2, Freq))
df.top.aiw60 <- top.pred.celltype.AIW60[order(top.pred.celltype.AIW60$Var1,-top.pred.celltype.AIW60$Freq),]
row.names(df.top.aiw60) <- NULL
df.top.aiw60$I <- row.names(df.top.aiw60)


# AST23 165 days predictions
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.2, seu.q$MBOAST23.thresh))
t.lables$Freq <- as.double(t.lables$Freq)
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity") + RotatedAxis() 

top.pred.celltype.AST23 <- as.data.frame(t.lables  %>% group_by(Var1)  %>% top_n(2, Freq))
df.top.AST23 <- top.pred.celltype.AST23[order(top.pred.celltype.AST23$Var1,-top.pred.celltype.AST23$Freq),]
row.names(df.top.AST23) <- NULL
df.top.AST23$I <- row.names(df.top.AST23)

# add the threshold Astro predictions 
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.2, seu.q$astro.pred.thresh))
t.lables$Freq <- as.double(t.lables$Freq)
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity") + RotatedAxis() 

top.pred.celltype.astro <- as.data.frame(t.lables  %>% group_by(Var1)  %>% top_n(2, Freq))
df.top.astro <- top.pred.celltype.astro[order(top.pred.celltype.astro$Var1,-top.pred.celltype.astro$Freq),]
row.names(df.top.astro) <- NULL
df.top.astro$I <- row.names(df.top.astro)

# add the neurons predictions 
t.lables <- as.data.frame(table(seu.q$RNA_snn_res.0.2, seu.q$da.pred.thresh))
t.lables$Freq <- as.double(t.lables$Freq)
ggplot(t.lables, aes(y = Freq, x = Var1, fill = Var2)) + geom_bar(position = "stack", stat= "identity") + RotatedAxis() 

top.pred.celltype.da <- as.data.frame(t.lables  %>% group_by(Var1)  %>% top_n(2, Freq))
df.top.da <- top.pred.celltype.da[order(top.pred.celltype.da$Var1,-top.pred.celltype.da$Freq),]
row.names(df.top.da) <- NULL
df.top.da$I <- row.names(df.top.da)

pred.table <- merge(df.top.AST23, df.top.aiw60, by = 'I', all = TRUE)
pred.table <- merge(pred.table, df.top.aiw120, by = 'I')
pred.table <- merge(pred.table, df.top.astro, by = 'I')
Warning in merge.data.frame(pred.table, df.top.astro, by = "I") :
  column names ‘Var1.x’, ‘Var2.x’, ‘Freq.x’, ‘Var1.y’, ‘Var2.y’, ‘Freq.y’ are duplicated in the result
pred.table <- merge(pred.table, df.top.da, by = 'I')
Warning in merge.data.frame(pred.table, df.top.da, by = "I") :
  column names ‘Var1.x’, ‘Var2.x’, ‘Freq.x’, ‘Var1.y’, ‘Var2.y’, ‘Freq.y’ are duplicated in the result
pred.table
NA
NA

Predicted cluster annotations 0 Unknown/ NPC 1 RG 2 astro 3 RG 4 neurons 5 RG

Look at gene lists with known markers

rg <- c("VIM","NES","PAX6","HES1","EAAT1","NCAD1","SOX2","FABP7")
DoHeatmap(seu.q, features = rg, size=3, angle =90, group.bar.height = 0.02)
Warning in DoHeatmap(seu.q, features = rg, size = 3, angle = 90, group.bar.height = 0.02) :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: NCAD1, EAAT1, PAX6, NES

DotPlot(seu.q, features = rg)+RotatedAxis()
Warning in FetchData.Seurat(object = object, vars = features, cells = cells) :
  The following requested variables were not found: EAAT1, NCAD1

Marker expression predictions Cluster 0 - unknown Cluster 1 - RG Cluster 2 - unknown Cluster 3 - RG cluster 4 - immature neurons Cluster 5 - RG, opc

Check the levels of RNA in each cluster

VlnPlot(seu.q, features = "nFeature_RNA")

Cluster 0 and 2 have fewer sequences than other groups and thus no markers Possibly remove these is they don’t come up with some markers

Find cluster markers

Idents(seu.q) <- 'RNA_snn_res.0.1'
ClusterMarkers <- FindAllMarkers(seu.q, only.pos = TRUE)
Calculating cluster 0

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~10s          
  |++                                                | 2 % ~09s          
  |++                                                | 3 % ~09s          
  |+++                                               | 5 % ~09s          
  |+++                                               | 6 % ~09s          
  |++++                                              | 7 % ~09s          
  |+++++                                             | 8 % ~08s          
  |+++++                                             | 9 % ~08s          
  |++++++                                            | 10% ~08s          
  |++++++                                            | 12% ~08s          
  |+++++++                                           | 13% ~08s          
  |+++++++                                           | 14% ~08s          
  |++++++++                                          | 15% ~08s          
  |+++++++++                                         | 16% ~08s          
  |+++++++++                                         | 17% ~08s          
  |++++++++++                                        | 19% ~08s          
  |++++++++++                                        | 20% ~07s          
  |+++++++++++                                       | 21% ~08s          
  |++++++++++++                                      | 22% ~07s          
  |++++++++++++                                      | 23% ~07s          
  |+++++++++++++                                     | 24% ~07s          
  |+++++++++++++                                     | 26% ~07s          
  |++++++++++++++                                    | 27% ~07s          
  |++++++++++++++                                    | 28% ~07s          
  |+++++++++++++++                                   | 29% ~07s          
  |++++++++++++++++                                  | 30% ~07s          
  |++++++++++++++++                                  | 31% ~07s          
  |+++++++++++++++++                                 | 33% ~06s          
  |+++++++++++++++++                                 | 34% ~06s          
  |++++++++++++++++++                                | 35% ~06s          
  |+++++++++++++++++++                               | 36% ~06s          
  |+++++++++++++++++++                               | 37% ~06s          
  |++++++++++++++++++++                              | 38% ~06s          
  |++++++++++++++++++++                              | 40% ~06s          
  |+++++++++++++++++++++                             | 41% ~06s          
  |+++++++++++++++++++++                             | 42% ~06s          
  |++++++++++++++++++++++                            | 43% ~05s          
  |+++++++++++++++++++++++                           | 44% ~05s          
  |+++++++++++++++++++++++                           | 45% ~05s          
  |++++++++++++++++++++++++                          | 47% ~05s          
  |++++++++++++++++++++++++                          | 48% ~05s          
  |+++++++++++++++++++++++++                         | 49% ~05s          
  |+++++++++++++++++++++++++                         | 50% ~05s          
  |++++++++++++++++++++++++++                        | 51% ~05s          
  |+++++++++++++++++++++++++++                       | 52% ~04s          
  |+++++++++++++++++++++++++++                       | 53% ~04s          
  |++++++++++++++++++++++++++++                      | 55% ~04s          
  |++++++++++++++++++++++++++++                      | 56% ~04s          
  |+++++++++++++++++++++++++++++                     | 57% ~04s          
  |++++++++++++++++++++++++++++++                    | 58% ~04s          
  |++++++++++++++++++++++++++++++                    | 59% ~04s          
  |+++++++++++++++++++++++++++++++                   | 60% ~04s          
  |+++++++++++++++++++++++++++++++                   | 62% ~04s          
  |++++++++++++++++++++++++++++++++                  | 63% ~03s          
  |++++++++++++++++++++++++++++++++                  | 64% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~03s          
  |++++++++++++++++++++++++++++++++++                | 66% ~03s          
  |++++++++++++++++++++++++++++++++++                | 67% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 70% ~03s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~03s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~03s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 78% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 80% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 94% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=09s  
Calculating cluster 1

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~23s          
  |++                                                | 2 % ~22s          
  |++                                                | 3 % ~21s          
  |+++                                               | 4 % ~22s          
  |+++                                               | 5 % ~21s          
  |++++                                              | 6 % ~21s          
  |++++                                              | 7 % ~21s          
  |+++++                                             | 8 % ~21s          
  |+++++                                             | 9 % ~21s          
  |++++++                                            | 10% ~20s          
  |++++++                                            | 11% ~20s          
  |+++++++                                           | 12% ~20s          
  |+++++++                                           | 13% ~19s          
  |++++++++                                          | 14% ~19s          
  |++++++++                                          | 15% ~19s          
  |+++++++++                                         | 16% ~19s          
  |+++++++++                                         | 18% ~18s          
  |++++++++++                                        | 19% ~18s          
  |++++++++++                                        | 20% ~18s          
  |+++++++++++                                       | 21% ~18s          
  |+++++++++++                                       | 22% ~17s          
  |++++++++++++                                      | 23% ~17s          
  |++++++++++++                                      | 24% ~17s          
  |+++++++++++++                                     | 25% ~17s          
  |+++++++++++++                                     | 26% ~16s          
  |++++++++++++++                                    | 27% ~16s          
  |++++++++++++++                                    | 28% ~16s          
  |+++++++++++++++                                   | 29% ~16s          
  |+++++++++++++++                                   | 30% ~15s          
  |++++++++++++++++                                  | 31% ~15s          
  |++++++++++++++++                                  | 32% ~15s          
  |+++++++++++++++++                                 | 33% ~15s          
  |++++++++++++++++++                                | 34% ~14s          
  |++++++++++++++++++                                | 35% ~14s          
  |+++++++++++++++++++                               | 36% ~14s          
  |+++++++++++++++++++                               | 37% ~14s          
  |++++++++++++++++++++                              | 38% ~14s          
  |++++++++++++++++++++                              | 39% ~13s          
  |+++++++++++++++++++++                             | 40% ~13s          
  |+++++++++++++++++++++                             | 41% ~13s          
  |++++++++++++++++++++++                            | 42% ~13s          
  |++++++++++++++++++++++                            | 43% ~12s          
  |+++++++++++++++++++++++                           | 44% ~12s          
  |+++++++++++++++++++++++                           | 45% ~12s          
  |++++++++++++++++++++++++                          | 46% ~12s          
  |++++++++++++++++++++++++                          | 47% ~12s          
  |+++++++++++++++++++++++++                         | 48% ~11s          
  |+++++++++++++++++++++++++                         | 49% ~11s          
  |++++++++++++++++++++++++++                        | 51% ~11s          
  |++++++++++++++++++++++++++                        | 52% ~11s          
  |+++++++++++++++++++++++++++                       | 53% ~10s          
  |+++++++++++++++++++++++++++                       | 54% ~10s          
  |++++++++++++++++++++++++++++                      | 55% ~10s          
  |++++++++++++++++++++++++++++                      | 56% ~10s          
  |+++++++++++++++++++++++++++++                     | 57% ~09s          
  |+++++++++++++++++++++++++++++                     | 58% ~09s          
  |++++++++++++++++++++++++++++++                    | 59% ~09s          
  |++++++++++++++++++++++++++++++                    | 60% ~09s          
  |+++++++++++++++++++++++++++++++                   | 61% ~09s          
  |+++++++++++++++++++++++++++++++                   | 62% ~08s          
  |++++++++++++++++++++++++++++++++                  | 63% ~08s          
  |++++++++++++++++++++++++++++++++                  | 64% ~08s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~08s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~07s          
  |++++++++++++++++++++++++++++++++++                | 67% ~07s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~07s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~07s          
  |++++++++++++++++++++++++++++++++++++              | 70% ~06s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~06s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~06s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~06s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~06s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~05s          
  |+++++++++++++++++++++++++++++++++++++++           | 76% ~05s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~05s          
  |++++++++++++++++++++++++++++++++++++++++          | 78% ~05s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~04s          
  |+++++++++++++++++++++++++++++++++++++++++         | 80% ~04s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~04s          
  |++++++++++++++++++++++++++++++++++++++++++        | 82% ~04s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~04s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~03s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~03s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=21s  
Calculating cluster 2

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~20s          
  |++                                                | 2 % ~20s          
  |++                                                | 3 % ~20s          
  |+++                                               | 4 % ~20s          
  |+++                                               | 5 % ~19s          
  |++++                                              | 6 % ~19s          
  |++++                                              | 7 % ~19s          
  |+++++                                             | 8 % ~19s          
  |+++++                                             | 9 % ~18s          
  |++++++                                            | 10% ~18s          
  |++++++                                            | 11% ~18s          
  |+++++++                                           | 12% ~18s          
  |+++++++                                           | 13% ~18s          
  |++++++++                                          | 14% ~18s          
  |++++++++                                          | 15% ~17s          
  |+++++++++                                         | 16% ~17s          
  |+++++++++                                         | 18% ~17s          
  |++++++++++                                        | 19% ~17s          
  |++++++++++                                        | 20% ~16s          
  |+++++++++++                                       | 21% ~16s          
  |+++++++++++                                       | 22% ~16s          
  |++++++++++++                                      | 23% ~16s          
  |++++++++++++                                      | 24% ~16s          
  |+++++++++++++                                     | 25% ~15s          
  |+++++++++++++                                     | 26% ~15s          
  |++++++++++++++                                    | 27% ~15s          
  |++++++++++++++                                    | 28% ~15s          
  |+++++++++++++++                                   | 29% ~14s          
  |+++++++++++++++                                   | 30% ~14s          
  |++++++++++++++++                                  | 31% ~14s          
  |++++++++++++++++                                  | 32% ~14s          
  |+++++++++++++++++                                 | 33% ~14s          
  |++++++++++++++++++                                | 34% ~13s          
  |++++++++++++++++++                                | 35% ~13s          
  |+++++++++++++++++++                               | 36% ~13s          
  |+++++++++++++++++++                               | 37% ~13s          
  |++++++++++++++++++++                              | 38% ~13s          
  |++++++++++++++++++++                              | 39% ~12s          
  |+++++++++++++++++++++                             | 40% ~12s          
  |+++++++++++++++++++++                             | 41% ~12s          
  |++++++++++++++++++++++                            | 42% ~12s          
  |++++++++++++++++++++++                            | 43% ~12s          
  |+++++++++++++++++++++++                           | 44% ~11s          
  |+++++++++++++++++++++++                           | 45% ~11s          
  |++++++++++++++++++++++++                          | 46% ~11s          
  |++++++++++++++++++++++++                          | 47% ~11s          
  |+++++++++++++++++++++++++                         | 48% ~10s          
  |+++++++++++++++++++++++++                         | 49% ~10s          
  |++++++++++++++++++++++++++                        | 51% ~10s          
  |++++++++++++++++++++++++++                        | 52% ~10s          
  |+++++++++++++++++++++++++++                       | 53% ~10s          
  |+++++++++++++++++++++++++++                       | 54% ~09s          
  |++++++++++++++++++++++++++++                      | 55% ~09s          
  |++++++++++++++++++++++++++++                      | 56% ~09s          
  |+++++++++++++++++++++++++++++                     | 57% ~09s          
  |+++++++++++++++++++++++++++++                     | 58% ~09s          
  |++++++++++++++++++++++++++++++                    | 59% ~08s          
  |++++++++++++++++++++++++++++++                    | 60% ~08s          
  |+++++++++++++++++++++++++++++++                   | 61% ~08s          
  |+++++++++++++++++++++++++++++++                   | 62% ~08s          
  |++++++++++++++++++++++++++++++++                  | 63% ~08s          
  |++++++++++++++++++++++++++++++++                  | 64% ~07s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~07s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~07s          
  |++++++++++++++++++++++++++++++++++                | 67% ~07s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~07s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~06s          
  |++++++++++++++++++++++++++++++++++++              | 70% ~06s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~06s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~06s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~05s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~05s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~05s          
  |+++++++++++++++++++++++++++++++++++++++           | 76% ~05s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~05s          
  |++++++++++++++++++++++++++++++++++++++++          | 78% ~04s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~04s          
  |+++++++++++++++++++++++++++++++++++++++++         | 80% ~04s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~04s          
  |++++++++++++++++++++++++++++++++++++++++++        | 82% ~04s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~03s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~03s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=20s  
Calculating cluster 3

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~15s          
  |++                                                | 2 % ~15s          
  |++                                                | 3 % ~15s          
  |+++                                               | 4 % ~15s          
  |+++                                               | 5 % ~15s          
  |++++                                              | 6 % ~15s          
  |++++                                              | 7 % ~14s          
  |+++++                                             | 9 % ~14s          
  |+++++                                             | 10% ~14s          
  |++++++                                            | 11% ~14s          
  |++++++                                            | 12% ~14s          
  |+++++++                                           | 13% ~14s          
  |+++++++                                           | 14% ~14s          
  |++++++++                                          | 15% ~13s          
  |++++++++                                          | 16% ~13s          
  |+++++++++                                         | 17% ~13s          
  |++++++++++                                        | 18% ~13s          
  |++++++++++                                        | 19% ~13s          
  |+++++++++++                                       | 20% ~12s          
  |+++++++++++                                       | 21% ~12s          
  |++++++++++++                                      | 22% ~12s          
  |++++++++++++                                      | 23% ~12s          
  |+++++++++++++                                     | 24% ~12s          
  |+++++++++++++                                     | 26% ~11s          
  |++++++++++++++                                    | 27% ~11s          
  |++++++++++++++                                    | 28% ~11s          
  |+++++++++++++++                                   | 29% ~11s          
  |+++++++++++++++                                   | 30% ~11s          
  |++++++++++++++++                                  | 31% ~10s          
  |++++++++++++++++                                  | 32% ~10s          
  |+++++++++++++++++                                 | 33% ~10s          
  |++++++++++++++++++                                | 34% ~10s          
  |++++++++++++++++++                                | 35% ~10s          
  |+++++++++++++++++++                               | 36% ~10s          
  |+++++++++++++++++++                               | 37% ~09s          
  |++++++++++++++++++++                              | 38% ~09s          
  |++++++++++++++++++++                              | 39% ~09s          
  |+++++++++++++++++++++                             | 40% ~09s          
  |+++++++++++++++++++++                             | 41% ~09s          
  |++++++++++++++++++++++                            | 43% ~09s          
  |++++++++++++++++++++++                            | 44% ~08s          
  |+++++++++++++++++++++++                           | 45% ~08s          
  |+++++++++++++++++++++++                           | 46% ~08s          
  |++++++++++++++++++++++++                          | 47% ~08s          
  |++++++++++++++++++++++++                          | 48% ~08s          
  |+++++++++++++++++++++++++                         | 49% ~08s          
  |+++++++++++++++++++++++++                         | 50% ~07s          
  |++++++++++++++++++++++++++                        | 51% ~07s          
  |+++++++++++++++++++++++++++                       | 52% ~07s          
  |+++++++++++++++++++++++++++                       | 53% ~07s          
  |++++++++++++++++++++++++++++                      | 54% ~07s          
  |++++++++++++++++++++++++++++                      | 55% ~07s          
  |+++++++++++++++++++++++++++++                     | 56% ~06s          
  |+++++++++++++++++++++++++++++                     | 57% ~06s          
  |++++++++++++++++++++++++++++++                    | 59% ~06s          
  |++++++++++++++++++++++++++++++                    | 60% ~06s          
  |+++++++++++++++++++++++++++++++                   | 61% ~06s          
  |+++++++++++++++++++++++++++++++                   | 62% ~06s          
  |++++++++++++++++++++++++++++++++                  | 63% ~06s          
  |++++++++++++++++++++++++++++++++                  | 64% ~05s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~05s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~05s          
  |++++++++++++++++++++++++++++++++++                | 67% ~05s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~05s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~05s          
  |++++++++++++++++++++++++++++++++++++              | 70% ~04s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~04s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~04s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~04s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~04s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~04s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~03s          
  |+++++++++++++++++++++++++++++++++++++++           | 78% ~03s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~03s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++         | 82% ~03s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=15s  
top5 <- ClusterMarkers %>% group_by(cluster) %>% top_n(n=5, wt = avg_log2FC)
DoHeatmap(seu.q, features = top5$gene, size=3, angle =90, group.bar.height = 0.02)

Markers of 2 are matching with 5 possibly merge these together Cluster 0 markers don’t look up regulated but the list is long

Look at the libraries


N1.c0 <- ClusterMarkers %>% filter(cluster == 0 & avg_log2FC > 0)
genes <- N1.c0$gene

N1.c0.Er <- enrichr(genes, databases = db)
Uploading data to Enrichr... Done.
  Querying Descartes_Cell_Types_and_Tissue_2021... Done.
  Querying CellMarker_Augmented_2021... Done.
  Querying Azimuth_Cell_Types_2021... Done.
Parsing results... Done.
plotEnrich(N1.c0.Er[[1]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")

plotEnrich(N1.c0.Er[[2]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")

plotEnrich(N1.c0.Er[[3]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")



N1.Er.genes.1 <- N1.c0.Er[[1]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.1

N1.Er.genes.2 <- N1.c0.Er[[2]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.2

N1.Er.genes.3 <- N1.c0.Er[[3]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.3

Add some cell type annotations


Idents(seu.q) <- 'RNA_snn_res.0.2'

cluster.ids <- c("Glia1","RG1","Glia2","RG2","NeuronsImmature","RG3")

names(cluster.ids) <- levels(seu.q)
seu.q <- RenameIdents(seu.q, cluster.ids)
seu.q$subgroups <- Idents(seu.q)

#DimPlot(seu.q, group.by = 'RNA_snn_res.0.2', label = TRUE)
DimPlot(seu.q, reduction = "umap", label = TRUE, group.by = 'subgroups', repel = TRUE)

NA
NA
NA
# save file
saveRDS(seu.q, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/objs/Glia2LabledSeu03102022.RDS")

Main cell groups


Idents(seu.q) <- 'RNA_snn_res.0.2'

cluster.ids <- c("RG","RG","RG","RG","NeuronsImmature","RG")

names(cluster.ids) <- levels(seu.q)
seu.q <- RenameIdents(seu.q, cluster.ids)
seu.q$Cell_Types <- Idents(seu.q)

#DimPlot(seu.q, group.by = 'RNA_snn_res.0.2', label = TRUE)
DimPlot(seu.q, reduction = "umap", label = TRUE, group.by = 'Cell_Types', repel = TRUE)


saveRDS(seu.q, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/objs/Glia2LabledSeu03102022.RDS")

Proportions of cell types

I’ll calculate the proportions for each cell type and make a table or plot in the comparison workbook.

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQpTaW5nbGUgY2VsbCBzZXEgYWZ0ZXIgc29ydGluZyBmb3IgUGhlbm9JRAoKc2FtcGxlMSA9IE5ldXJvbnMxCnNhbXBsZTIgPSBOZXVyb25zMgpzYW1wbGUzID0gR2xpYTEgLSBBc3Ryb2N5dGVzIChDRDQ0KykKc2FtcGxlNCA9IEdsaWEyIC0gUmFkaWFsIEdsaWEgKENENDQtKQoKSW4gSFBDIEkgaGF2ZSBydW4gc3RlcHMgb2Ygc2NybmFib3ggKGN1c3RvbSBwaXBlbGluZSBpbiBwcm9ncmVzcykKMS4gQ2VsbCBSYW5nZXIgZm9yIGZlYXR1cmUgc2VxCjIuIENyZWF0ZSBTZXVyYXQgT2JqZWN0cyAKMy4gQXBwbHkgbWluaW11bSBmaWx0ZXJpbmcgYW5kIGNhbGN1bGF0ZSBwZXJjZW50IG1pdG9jaG9uZHJpYS4KCkkgaGF2ZSB0ZWNobmljYWwgMyByZXBsaWNhdGVzIHdpdGggaGFzaHRhZyBsYWJlbHMgYXQgdGhpcyBwb2ludCBJIGhhdmVuJ3QgeWV0IGRlbXVsdGlwbGV4IHRoZSBoYXNodGFncy4gVGhlIGRhdGEgaGVyZSB3aWxsIGJlIHRyZWF0ZWQgYXMgb25lIHNhbXBsZS4gIEkgc29ydGVkIHRocmVlIHNlcGFyYXRlIHNhbXBsZXMgYW5kIHBvb2xlZCB0aGVtIHRvZ2V0aGVyLiAKCgpgYGB7cn0KIyBzZXQgdXAgdGhlIGVudmlyb25tZW50CgpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShkcGx5cikKbGlicmFyeShNYXRyaXgpCmxpYnJhcnkoZ2dwbG90MikKCiNybShsaXN0ID0gbHMoKSkKCgpgYGAKCgpSZWFkIGluIHRoZSBzZXVyYXQgb2JqZWN0cyBtYWRlIGluIGNvbXB1dGUgY2FuYWRhCgpgYGB7cn0KCiMgdGhpcyBzZWVtcyB0byBuZXZlciBsb2FkIEknbGwgdXNlIHN0ZXAgMyBvdXRwdXQgdGhhdCBoYXMgc29tZSBmaWx0ZXJpbmcgCiMgbkZlYXR1cmVfUk5BID4gMTgwIGFuZCBwZXJjZW50Lm10IDwgMjUKCnBhdGh3YXkgPC0gIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL1BoZW5vSUQvc2NSTkFzZXFTb3J0ZWQvb2Jqcy8iCgpOZXVyb25zMSA8LSByZWFkUkRTKHBhc3RlKHBhdGh3YXksInNldTEucmRzIixzZXAgPSAiIikpCk5ldXJvbnMyIDwtIHJlYWRSRFMocGFzdGUocGF0aHdheSwic2V1Mi5yZHMiLHNlcCA9ICIiKSkKR2xpYTEgPC0gcmVhZFJEUyhwYXN0ZShwYXRod2F5LCJzZXUzLnJkcyIsc2VwID0gIiIpKQpHbGlhMiA8LSByZWFkUkRTKHBhc3RlKHBhdGh3YXksInNldTQucmRzIixzZXAgPSAiIikpCgpOZXVyb25zMQpOZXVyb25zMgpHbGlhMQpHbGlhMgoKCmBgYAoKCkhhdmUgYSBsb29rIGF0IHRoZSBvYmplY3RzIHRoYXQgYWxyZWFkeSBoYXZlIHNvbWUgZmlsdGVyaW5nCgoKU2VlIHRoZSB2aW9saW4gcGxvdHMgCgpgYGB7cn0KClZsblBsb3QoTmV1cm9uczEsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIsICJuQ291bnRfUk5BIiwgInBlcmNlbnQubXQiKSwgbmNvbCA9IDMpCgpWbG5QbG90KE5ldXJvbnMxLCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiKSwgeS5tYXggPSA1MDApClZsblBsb3QoTmV1cm9uczEsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5Db3VudF9STkEiKSwgeS5tYXggPSAyMDAwKQoKCgojIGZpbHRlciBtb3JlIGNlbGxzCgpOZXVyb24xLmZ0IDwtIHN1YnNldChOZXVyb25zMSwgc3Vic2V0ID0gbkZlYXR1cmVfUk5BID4gMjUwICYgbkNvdW50X1JOQSA+IDI1MCAmIG5Db3VudF9STkEgPCAxMDAwMCkgCk5ldXJvbjEuZnQKCiMgMzM1NDEgZmVhdHVyZXMgYWNyb3NzIDE4MzMgc2FtcGxlcwoKCmBgYAoKTmV1cm9ucyAyIC0gQ0Q1NisrCgpgYGB7cn0KClZsblBsb3QoTmV1cm9uczIsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIsICJuQ291bnRfUk5BIiwgInBlcmNlbnQubXQiKSwgbmNvbCA9IDMpClZsblBsb3QoTmV1cm9uczIsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIpLCB5Lm1heCA9IDUwMCkKVmxuUGxvdChOZXVyb25zMiwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiksIHkubWF4ID0gMTAwMCkKVmxuUGxvdChOZXVyb25zMiwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkNvdW50X1JOQSIpLCB5Lm1heCA9IDIwMDApCgoKCiMgZmlsdGVyIG1vcmUgY2VsbHMKCk5ldXJvbjIuZnQgPC0gc3Vic2V0KE5ldXJvbnMyLCBzdWJzZXQgPSBuRmVhdHVyZV9STkEgPiA1MDAgJiBuQ291bnRfUk5BID4gNTAwICYgbkNvdW50X1JOQSA8IDEwMDAwKSAKTmV1cm9uMi5mdAoKCgpgYGAKCkdsaWExIC0gQXN0cm9jeXRlIGRhdGEKCmBgYHtyfQoKVmxuUGxvdChHbGlhMSwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiwgIm5Db3VudF9STkEiLCAicGVyY2VudC5tdCIpLCBuY29sID0gMykKClZsblBsb3QoR2xpYTEsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIpLCB5Lm1heCA9IDUwMDApClZsblBsb3QoR2xpYTEsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIpLCB5Lm1heCA9IDEwMDApClZsblBsb3QoR2xpYTEsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5Db3VudF9STkEiKSwgeS5tYXggPSAxMDAwKQpWbG5QbG90KEdsaWExLCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuQ291bnRfUk5BIiksIHkubWF4ID0gMTIwMDApCgoKIyBleHRyZW1lIGZpbHRlcgoKR2xpYTEuZnQgPC0gc3Vic2V0KEdsaWExLCBzdWJzZXQgPSBuRmVhdHVyZV9STkEgPiA1MDAgJiBuQ291bnRfUk5BID4gMzAwICYgbkNvdW50X1JOQSA8IDEwMDAwKSAKR2xpYTEuZnQKR2xpYTEKClZsblBsb3QoR2xpYTEuZnQsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIsICJuQ291bnRfUk5BIiwgInBlcmNlbnQubXQiKSwgbmNvbCA9IDMpCgoKCgoKYGBgCgoKR2xpYTIgLSBSYWRpYWwgR2xpYQoKYGBge3J9CgojIyBGaWx0ZXIgR2xpYSAyClZsblBsb3QoR2xpYTIsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIsICJuQ291bnRfUk5BIiwgInBlcmNlbnQubXQiKSwgbmNvbCA9IDMpCgpWbG5QbG90KEdsaWEyLCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiKSwgeS5tYXggPSA1MDAwKQpWbG5QbG90KEdsaWEyLCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiKSwgeS5tYXggPSAxMDAwKQpWbG5QbG90KEdsaWEyLCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuQ291bnRfUk5BIiksIHkubWF4ID0gMTAwMCkKVmxuUGxvdChHbGlhMiwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkNvdW50X1JOQSIpLCB5Lm1heCA9IDEyMDAwKQoKCiMgZXh0cmVtZSBmaWx0ZXIKCkdsaWEyLmZ0IDwtIHN1YnNldChHbGlhMSwgc3Vic2V0ID0gbkZlYXR1cmVfUk5BID4gNTAwICYgbkNvdW50X1JOQSA+IDUwMCAmIG5Db3VudF9STkEgPCAxMDAwMCkgCkdsaWEyLmZ0CgoKVmxuUGxvdChHbGlhMS5mdCwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiwgIm5Db3VudF9STkEiLCAicGVyY2VudC5tdCIpLCBuY29sID0gMykKCiMgdGhlcmUgYXJlIHNvIG1hbnkgc3Vwb3NlZCBjZWxscyBJIGFtIGNvbmNlcm5lZCB0aGUgaGlnaCByZWFkIGNlbGxzIGFyZSBhY3R1YWxseSBkb3VibGV0cy4gCgoKCmBgYAoKCkFuYWx5emUgZWFjaCBkYXRhc2V0IC0gZ2V0IGNsdXN0ZXJzIAoKYGBge3J9CgojIGNsdXN0ZXIgdGhlIG5ldXJvbnMKc2V1IDwtIE5ldXJvbjEuZnQKc2V1JG9yaWcuaWRlbnQgPC0gJ05ldXJvbnMxJwoKc2V1IDwtIE5vcm1hbGl6ZURhdGEoc2V1LCBub3JtYWxpemF0aW9uLm1ldGhvZCA9ICJMb2dOb3JtYWxpemUiLCBzY2FsZS5mYWN0b3IgPSAxMDAwMCkKc2V1IDwtIEZpbmRWYXJpYWJsZUZlYXR1cmVzKHNldSwgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSAyMDAwKQojIElkZW50aWZ5IHRoZSAxMCBtb3N0IGhpZ2hseSB2YXJpYWJsZSBnZW5lcwp0b3AxMCA8LSBoZWFkKFZhcmlhYmxlRmVhdHVyZXMoc2V1KSwgMTApCiMgcGxvdCB2YXJpYWJsZSBmZWF0dXJlcyB3aXRoIGFuZCB3aXRob3V0IGxhYmVscwpwbG90MSA8LSBWYXJpYWJsZUZlYXR1cmVQbG90KHNldSkKcGxvdDIgPC0gTGFiZWxQb2ludHMocGxvdCA9IHBsb3QxLCBwb2ludHMgPSB0b3AxMCwgcmVwZWwgPSBUUlVFKQoKCgpzZXUgPC0gU2NhbGVEYXRhKHNldSkKc2V1IDwtIFJ1blBDQShzZXUpCklkZW50cyhzZXUpIDwtICdvcmlnLmlkZW50JwpwbG90IDwtIERpbVBsb3Qoc2V1LCByZWR1Y3Rpb24gPSAicGNhIikKCgpwbG90MyA8LSBFbGJvd1Bsb3Qoc2V1LG5kaW1zID0gNTApCnBsb3QzCgpwbG90MgpwbG90CgoKCmBgYAoKYGBge3J9CgojIHVtYXAKCnNldSA8LSBSdW5VTUFQKHNldSwgcmVkdWN0aW9uID0gInBjYSIsIG4ubmVpZ2hib3JzID0gNDMsIGRpbXMgPSAxOjI1KQpEaW1QbG90KHNldSwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikKCgoKYGBgCgpNYWtlIHRoZSBjbHVzdGVycyBOZXVyb25zMQoKYGBge3J9CgpzZXUgPC0gRmluZE5laWdoYm9ycyhzZXUsIGRpbXMgPSAxOjI1LCBrLnBhcmFtID0gNDMpCnNldSA8LSBGaW5kQ2x1c3RlcnMoc2V1LCByZXNvbHV0aW9uID0gYygwLDAuMiwwLjI1LDAuNSwwLjgpKQpzZXUgPC0gRmluZENsdXN0ZXJzKHNldSwgcmVzb2x1dGlvbiA9IGMoMS4yKSkKCmxpYnJhcnkoY2x1c3RyZWUpCmNsdXN0cmVlKHNldSwgcHJlZml4ID0gIlJOQV9zbm5fcmVzLiIpCkRpbVBsb3Qoc2V1KQoKYGBgCgpgYGB7cn0KIyBsb29rIGEgbG90IGF0IHRoZSBjbHVzZXJzCgpWbG5QbG90KHNldSwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIGdyb3VwLmJ5ID0gJ3NldXJhdF9jbHVzdGVycycsIG5jb2wgPSAxKQojIHRoZXNlIGNlbGxzIG1pZ2h0IGJlIGdyb3VwaW5nIGJ5IC0gaG93IG11Y2ggTVQgYW5kIG51bWJlciBvZiBGZWF0dXJlcwojIGNsdXN0ZXJzIDQsNSw2IGhhdmUgbW9yZSBmZWF0dXJlcwoKVmxuUGxvdChzZXUsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiwgIm5Db3VudF9STkEiLCAicGVyY2VudC5tdCIpLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjI1JywgbmNvbCA9IDEpCiMgaGVyZSBjbHVzdGVyIDMgaGFzIGhpZ2hlciBleHByZXNzaW9uLCBjbHVzdGVyIDEgYW5kIDQgaGF2ZSBzaW1pbGFyIEZlYXR1cmVzIFJOQQojIGNsdXN0ZXIgMCBoYXMgaGlnaGVyIHBlcmNlbnQgTVQgbGV2ZWxzCgpWbG5QbG90KHNldSwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuNScsIG5jb2wgPSAxKQpWbG5QbG90KHNldSwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuMicsIG5jb2wgPSAxKQojIG5vdyBvbmx5IGNsdXN0ZXIgMCBoYXZlIGhpZ2ggTVQgYW5kIGxvdyBmZWF0dXJlcywgY2x1c3RlcnMgMSwyLDMgaGF2ZSBzaW1pdWxhciBSTkEgYW5kIENvdW50cwoKYGBgCgpGaW5kIHRoZSBjbHVzdGVyIG1hcmtlcnMgZm9yIE5ldXJvbnMxCgpgYGB7cn0KSWRlbnRzKHNldSkgPC0gJ1JOQV9zbm5fcmVzLjAuMicKQ2x1c3Rlck1hcmtlcnMgPC0gRmluZEFsbE1hcmtlcnMoc2V1KQoKdG9wNSA8LSBDbHVzdGVyTWFya2VycyAlPiUgZ3JvdXBfYnkoY2x1c3RlcikgJT4lIHRvcF9uKG49NSwgd3QgPSBhdmdfbG9nMkZDKQpEb0hlYXRtYXAoc2V1LCBmZWF0dXJlcyA9IHRvcDUkZ2VuZSwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjInKQoKCiN3cml0ZS5jc3YoQ2x1c3Rlck1hcmtlcnMsICIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9QaGVub0lEL3NjUk5Bc2VxU29ydGVkL0NsdXN0ZXJNYXJrZXJzX25ldXJvbnMxX3JlczAyNS5jc3YiKQoKCndyaXRlLmNzdihDbHVzdGVyTWFya2VycywgIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL1BoZW5vSUQvc2NSTkFzZXFTb3J0ZWQvQ2x1c3Rlck1hcmtlcnNfbmV1cm9uczFfcmVzMDIuY3N2IikKCmBgYAoKYGBge3J9CkRpbVBsb3Qoc2V1LCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjInLCByZWR1Y3Rpb24gPSAndW1hcCcpCgpgYGAKCgpHZXQgdGhlIG1vc3QgaGlnaGx5IGV4cHJlc3NlZCBnZW5lcyBpbiB0aGUgdG90YWwgZGF0YSAoTmV1cm9uczEpCgoKYGBge3J9CgpwYXIobWFyID0gYyg0LCA4LCAyLCAxKSkKQyA8LSBzZXVAYXNzYXlzJFJOQUBjb3VudHMKQyA8LSBNYXRyaXg6OnQoTWF0cml4Ojp0KEMpL01hdHJpeDo6Y29sU3VtcyhDKSkgKiAxMDAKbW9zdF9leHByZXNzZWQgPC0gb3JkZXIoYXBwbHkoQywgMSwgbWVkaWFuKSwgZGVjcmVhc2luZyA9IFQpWzI1OjFdCmJveHBsb3QoYXMubWF0cml4KHQoQ1ttb3N0X2V4cHJlc3NlZCwgXSkpLCBjZXggPSAwLjEsIGxhcyA9IDEsIHhsYWIgPSAiJSB0b3RhbCBjb3VudCBwZXIgY2VsbCIsCiAgICBjb2wgPSAoc2NhbGVzOjpodWVfcGFsKCkpKDI1KVsxOjI1XSwgaG9yaXpvbnRhbCA9IFRSVUUpCgojIGxpa2UgaW4gdGhlIHR1dG9yaWFsIEknbSBmb2xsb3dpbmcgTUFMQVQxIGlzIHRoZSB0b3AgbW9zdCBleHByZXNzZWQgZ2VuZS4gIFRoZSB0b3AgZ2VuZXMgYXJlIGEgbG90IG9mIE1UIGFuZCBSaWJvc29tYWwgZ2VuZXMKCnNldVtbInBlcmNlbnQucmIiXV0gPC0gUGVyY2VudGFnZUZlYXR1cmVTZXQoc2V1LCBwYXR0ZXJuID0gIl5SUCIpCgpWbG5QbG90KHNldSwgZmVhdHVyZXMgPSAicGVyY2VudC5yYiIsIGdyb3VwLmJ5ID0gIlJOQV9zbm5fcmVzLjAuMiIpCgoKCmBgYAoKRmlsdGVycyBvdXQgc3BlY2lmaWMgZ2VuZXMKCmBgYHtyfQoKc2V1LmZ0IDwtIHNldVshZ3JlcGwoIk1BTEFUMSIsIHJvd25hbWVzKHNldSkpLCBdCnNldS5mdCA8LSBzZXUuZnRbIWdyZXBsKCJeTVQtIiwgcm93bmFtZXMoc2V1LmZ0KSksIF0KCiMgdGhpcyBmaWx0ZXJlZCBvYmplY3QgbWlnaHQgY2x1c3RlciBkaWZmZXJlbnRseQojIGZvciBub3cgSSdtIGdvaW5nIHRvIG1vdmUgb24gdG8gZG91YmxldCBkZXRlY3Rpb24KCgpgYGAKCgoKVHJ5IHRvIGZpbmQgZG91YmxldHMgd2l0aCBkb3VibGV0IGZpbmRlcgoKYGBge3J9CnJlbW90ZXM6Omluc3RhbGxfZ2l0aHViKCdjaHJpcy1tY2dpbm5pcy11Y3NmL0RvdWJsZXRGaW5kZXInKQpzdXBwcmVzc01lc3NhZ2VzKHJlcXVpcmUoRG91YmxldEZpbmRlcikpCgoKYGBgCgpgYGB7cn0KCnNldS5kID0gRmluZFZhcmlhYmxlRmVhdHVyZXMoc2V1LCB2ZXJib3NlID0gRikKc2V1LmQgPSBTY2FsZURhdGEoc2V1LmQsIHZhcnMudG8ucmVncmVzcyA9IGMoIm5GZWF0dXJlX1JOQSIsICJwZXJjZW50Lm10IiksCiAgICB2ZXJib3NlID0gRikKc2V1LmQgPSBSdW5QQ0Eoc2V1LmQsIHZlcmJvc2UgPSBGLCBucGNzID0gMjApCnNldS5kID0gUnVuVU1BUChzZXUuZCwgZGltcyA9IDE6MTAsIHZlcmJvc2UgPSBGKQoKbkV4cCA8LSByb3VuZChuY29sKHNldS5kKSAqIDAuMDYpICAjIGV4cGVjdCA2JSBkb3VibGV0cwpzZXUuZCA8LSBkb3VibGV0RmluZGVyX3YzKHNldS5kLCBwTiA9IDAuMjUsIHBLID0gMC4wOSwgbkV4cCA9IG5FeHAsIFBDcyA9IDE6MTApCgoKIyBuYW1lIG9mIHRoZSBERiBwcmVkaWN0aW9uIGNhbiBjaGFuZ2UsIHNvIGV4dHJhY3QgdGhlIGNvcnJlY3QgY29sdW1uIG5hbWUuCkRGLm5hbWUgPSBjb2xuYW1lcyhzZXUuZEBtZXRhLmRhdGEpW2dyZXBsKCJERi5jbGFzc2lmaWNhdGlvbiIsIGNvbG5hbWVzKHNldS5kQG1ldGEuZGF0YSkpXQoKCgpjb3dwbG90OjpwbG90X2dyaWQobmNvbCA9IDIsIERpbVBsb3Qoc2V1LmQsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKSArIE5vQXhlcygpLAogICAgRGltUGxvdChzZXUuZCwgZ3JvdXAuYnkgPSBERi5uYW1lKSArIE5vQXhlcygpKQoKCmBgYAoKRG8gdGhlIGRvdWJsZSBjZWxscyBoYXZlIG1vcmUgZ2VuZXMgdGhhbiB0aGUgc2luZ2xldD8/CgpgYGB7cn0KClZsblBsb3Qoc2V1LmQsIGZlYXR1cmVzID0gIm5GZWF0dXJlX1JOQSIsIGdyb3VwLmJ5ID0gREYubmFtZSwgcHQuc2l6ZSA9IDAuMSkKCgpgYGAKCiMgcmVtb3ZlIHRoZSBkb3VibGV0cwoKYGBge3J9CgpzZXUuZCA8LSBzZXUuZFssIHNldS5kQG1ldGEuZGF0YVssIERGLm5hbWVdPT0gIlNpbmdsZXQiXQpkaW0oc2V1LmQpCmRpbShzZXUpCgojIHJlbW92ZWQgYWJvdXQgMTAwIGNlbGxzCgoKCgpgYGAKCgpTYXZlIHRoZSBmaWx0ZXJlZCwgZG91YmxldCByZW1vdmVkIE5ldXJvbnMgb2JqZWN0IApSZS1ydW4gUENBIGZvciBjbHVzdGVyaW5nIAoKYGBge3J9CgpzYXZlUkRTKHNldS5kLCAiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvUGhlbm9JRC9zY1JOQXNlcVNvcnRlZC9vYmpzL05ldXJvbnNGaWx0ZXJlZFNldTI4MDkyMDIyLlJEUyIpCgpgYGAKCgpEQXN1Ymdyb3VwcyBkYXRhIGhhcyBub3QgYmUgcmUtcHJvY2Vzc2VkClJ1biBzdGFuZGFyZCB3b3JrZmxvdyBjaHVuawoKYGBge3J9Cgojc2V1IDwtIHJlYWRSRFMoIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL01hY29za29fRGF0YS9QRF9kYS5SZHMiKQojc2V1IDwtIEFJVzYwCnNldSA8LSBOb3JtYWxpemVEYXRhKHNldSwgbm9ybWFsaXphdGlvbi5tZXRob2QgPSAiTG9nTm9ybWFsaXplIiwgc2NhbGUuZmFjdG9yID0gMTAwMDApCnNldSA8LSBGaW5kVmFyaWFibGVGZWF0dXJlcyhzZXUsIHNlbGVjdGlvbi5tZXRob2QgPSAidnN0IiwgbmZlYXR1cmVzID0gMjAwMCkKc2V1IDwtIFNjYWxlRGF0YShzZXUpCnNldSA8LSBSdW5QQ0Eoc2V1KQpzZXUgPC0gUnVuVU1BUChzZXUsIHJlZHVjdGlvbiA9ICJwY2EiLCBuLm5laWdoYm9ycyA9IDE1OSwgZGltcyA9IDE6MzApCkRpbVBsb3Qoc2V1LCByZWR1Y3Rpb24gPSAidW1hcCIpCgojc2F2ZVJEUyhzZXUsICIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9NYWNvc2tvX0RhdGEvREFzdWJncm91cHNfcHJvY2Vzc2VkLlJkcyIpCgojbm90ZSBteSBBSVcgNjAgZGF5cyBkYXRhIGFsc28gZGlkbid0IGhhdmUgdGhlIFBDQSBzYXZlZCAKIyByYW4gY29kZSBjaHVuY2sgd2l0aCBuLm5laWdoYm9ycyA9IDEyMyAKIyBzYXZlUkRTKHNldSwgIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL0FJV3RyaW82MGRheXMvQVdJMDAyUGFya2luS09QaW5rS082MGRheXNfbGFiZWxzXzE0MDUyMDIyLnJkcyIpCgoKYGBgCgoKQW5ub3RhdGUgY2x1c3RlcnMKVXNlOiBPcmdhbm9pZCBkYXRhLCBwdWJsaWMgYnJhaW4gZGF0YSAoTGFNYW5ubywgTGFrZSwgTWFzY2FrbykKCgpgYGB7cn0KCiMgdGhpcyBpcyBzb21lIHJlZmVyZW5jZSBkYXRhCgojIFNOQ0EgYW5kIGNvbnRyb2wgbWlkYnJhaW4gb3JnYW5vaWRzIDE2NSBkYXlzIGluIGN1bHR1cmUKTUJPIDwtIHJlYWRSRFMoIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL0FTVDIzX0JyYWluQ29tbS9NQk9jbHVzdGVyc19uYW1lczI5MDcyMDIxLnJkcyIpCgojIE1pZGJyYWluICBBSVcwMDIgMTIwIGRheXMgaW4gY3VsdHVyZQpBSVdNQk8gPC0gcmVhZFJEUygiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvQUlXdHJpbzEyMGRheXMvTU9pbnRlZ3JhdGVkQ2x1c3RlcksxMjNyZXMwLjgubmFtZXNfbm92MTZfMjAyMSIpCgojIE1pZGJyYWluIEFJVzAwMiA2MCBkYXlzIGluIGN1bHR1cmUKCkFJVzYwIDwtIHJlYWRSRFMoIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL0FJV3RyaW82MGRheXMvQVdJMDAyUGFya2luS09QaW5rS082MGRheXNfbGFiZWxzXzE0MDUyMDIyLnJkcyIpCgojIERBIG5ldXJvbiBzdWJ0eXBlcyBmcm9tIHBvc3Rtb3J0ZW0gYnJhaW4gS2FtYXRoIGV0IGFsIDIwMjIKREFzdWJ0eXBlcyA8LSByZWFkUkRTKCIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9NYWNvc2tvX0RhdGEvREFzdWJncm91cHNfcHJvY2Vzc2VkLlJkcyIpCgoKIyBxdWVyeQpzZXUucSA8LSByZWFkUkRTKCIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9QaGVub0lEL3NjUk5Bc2VxU29ydGVkL29ianMvTmV1cm9uc0ZpbHRlcmVkU2V1MjgwOTIwMjIuUkRTIikKCgojZmlyc3QgcHJlZGljdCB3aXRoIHRoZSBNQk8gZGF0YQpJZGVudHMoTUJPKSA8LSAiY2x1c3Rlcl9sYWJlbHMiCkRlZmF1bHRBc3NheShNQk8pIDwtICJSTkEiCgojIGZpbmQgdGhlIHJlZmVyZW5jZSBhbmNob3JzCnByaW50KCJmaW5kaW5nIHJlZmVyZW5jZSBhbmNob3JzIikKYW5jaG9ycyA8LSBGaW5kVHJhbnNmZXJBbmNob3JzKHJlZmVyZW5jZSA9IE1CTyAscXVlcnkgPSBzZXUucSwgZGltcyA9IDE6MjUpCnByaW50KCJnZXR0aW5nIHByZWRpY3Rpb25zIikKcHJlZGljdGlvbnMgPC0gVHJhbnNmZXJEYXRhKGFuY2hvcnNldCA9IGFuY2hvcnMsIHJlZmRhdGEgPSBNQk8kY2x1c3Rlcl9sYWJlbHMpCnNldS5xIDwtIEFkZE1ldGFEYXRhKHNldS5xLCBtZXRhZGF0YSA9IHByZWRpY3Rpb25zKQpwcmludCh0YWJsZShzZXUucSRwcmVkaWN0ZWQuaWQpKQoKSWRlbnRzKHNldS5xKSA8LSAncHJlZGljdGVkLmlkJwojIGFkZCBuZXcgZGF0YXNsb3QgZm9yIE1CTyBwcmVkaWN0ZWQgSUQgdG8gbWFrZSB0aGUgbmV4dCBwcmVkaWN0aW9uCnNldS5xJE1CT0FTVDIzLnByZWQgPC0gSWRlbnRzKHNldS5xKQpEaW1QbG90KHNldS5xLCBncm91cC5ieSA9ICdNQk9BU1QyMy5wcmVkJywgbGFiZWwgPSBUUlVFKQogCiMjIGNoZWNrIHRoZSBwcm9wb3J0aW9uIG9mIGNlbGwgdHlwZXMgcHJlZGljdGVkIGluIGVhY2ggY2x1c3Rlcgp0LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuMiwgc2V1LnEkcHJlZGljdGVkLmlkKSkKcHIudC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZShwcm9wLnRhYmxlKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuMiwgc2V1LnEkcHJlZGljdGVkLmlkKSkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCgoKIyB0cnkgYmFyIGNoYXJ0CmdncGxvdCh0LmxhYmxlcywgYWVzKHkgPSBGcmVxLCB4ID0gVmFyMSwgZmlsbCA9IFZhcjIpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdD0gImlkZW50aXR5IikKCiMgY2x1c3RlcnMgZG9uJ3QgYnJlYWsgdXAgYnkgdGhlIHByZWRpY3RlZCBjZWxsIHR5cGVzCgojIyMjIyMjIyMjIyMgYW5vdGhlciBwcmVkaWN0aW9ucyBub3cgdXNpbmcgdGhlIEFJVyBvcmdhbm9pZHMKCklkZW50cyhBSVdNQk8pIDwtICJyZXMwOG5hbWVzIgpEZWZhdWx0QXNzYXkoQUlXTUJPKSA8LSAiUk5BIgoKYW5jaG9ycyA8LSBGaW5kVHJhbnNmZXJBbmNob3JzKHJlZmVyZW5jZSA9IEFJV01CTyAscXVlcnkgPSBzZXUucSwgZGltcyA9IDE6MjUpCnByaW50KCJnZXR0aW5nIHByZWRpY3Rpb25zIikKcHJlZGljdGlvbnMgPC0gVHJhbnNmZXJEYXRhKGFuY2hvcnNldCA9IGFuY2hvcnMsIHJlZmRhdGEgPSBBSVdNQk8kcmVzMDhuYW1lcykKc2V1LnEgPC0gQWRkTWV0YURhdGEoc2V1LnEsIG1ldGFkYXRhID0gcHJlZGljdGlvbnMpCnByaW50KHRhYmxlKHNldS5xJHByZWRpY3RlZC5pZCkpCgpJZGVudHMoc2V1LnEpIDwtICdwcmVkaWN0ZWQuaWQnCiMgYWRkIG5ldyBkYXRhc2xvdCBmb3IgTUJPIHByZWRpY3RlZCBJRCB0byBtYWtlIHRoZSBuZXh0IHByZWRpY3Rpb24Kc2V1LnEkTUJPQUlXLnByZWQgPC0gSWRlbnRzKHNldS5xKQpEaW1QbG90KHNldS5xLCBncm91cC5ieSA9ICdNQk9BSVcucHJlZCcsIGxhYmVsID0gVFJVRSkKIAojIyBjaGVjayB0aGUgcHJvcG9ydGlvbiBvZiBjZWxsIHR5cGVzIHByZWRpY3RlZCBpbiBlYWNoIGNsdXN0ZXIKdC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShzZXUucSRSTkFfc25uX3Jlcy4wLjIsIHNldS5xJHByZWRpY3RlZC5pZCkpCnByLnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUocHJvcC50YWJsZSh0YWJsZShzZXUucSRSTkFfc25uX3Jlcy4wLjIsIHNldS5xJHByZWRpY3RlZC5pZCkpKQp0LmxhYmxlcyRGcmVxIDwtIGFzLmRvdWJsZSh0LmxhYmxlcyRGcmVxKQoKCiMgdHJ5IGJhciBjaGFydApnZ3Bsb3QodC5sYWJsZXMsIGFlcyh5ID0gRnJlcSwgeCA9IFZhcjEsIGZpbGwgPSBWYXIyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ICJpZGVudGl0eSIpCgojIHRoZSBwcmVkaWN0ZWQgY2VsbCB0eXBlcyBtYWtlIG1vcmUgc2Vuc2UgZnJvbSB0aGUgQUlXMDAyIG9yZ2Fub2lkCiMgbm93IHByZWRpY3Qgd2l0aCB0aGUgQUlXMDAyIDYwIGRheXMgb3JnYW5vaWQKCklkZW50cyhBSVc2MCkgPC0gImNsdXN0ZXIuaWRzIgpEZWZhdWx0QXNzYXkoQUlXNjApIDwtICJSTkEiCgphbmNob3JzIDwtIEZpbmRUcmFuc2ZlckFuY2hvcnMocmVmZXJlbmNlID0gQUlXNjAsIHF1ZXJ5ID0gc2V1LnEsIGRpbXMgPSAxOjI1KQpwcmludCgiZ2V0dGluZyBwcmVkaWN0aW9ucyIpCnByZWRpY3Rpb25zIDwtIFRyYW5zZmVyRGF0YShhbmNob3JzZXQgPSBhbmNob3JzLCByZWZkYXRhID0gQUlXNjAkY2x1c3Rlci5pZHMpIApzZXUucSA8LSBBZGRNZXRhRGF0YShzZXUucSwgbWV0YWRhdGEgPSBwcmVkaWN0aW9ucykKcHJpbnQodGFibGUoc2V1LnEkcHJlZGljdGVkLmlkKSkKCklkZW50cyhzZXUucSkgPC0gJ3ByZWRpY3RlZC5pZCcKIyBhZGQgbmV3IGRhdGFzbG90IGZvciBNQk8gcHJlZGljdGVkIElEIHRvIG1ha2UgdGhlIG5leHQgcHJlZGljdGlvbgpzZXUucSRBSVc2MC5wcmVkIDwtIElkZW50cyhzZXUucSkKRGltUGxvdChzZXUucSwgZ3JvdXAuYnkgPSAnQUlXNjAucHJlZCcsIGxhYmVsID0gVFJVRSkKIAojIyBjaGVjayB0aGUgcHJvcG9ydGlvbiBvZiBjZWxsIHR5cGVzIHByZWRpY3RlZCBpbiBlYWNoIGNsdXN0ZXIKdC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShzZXUucSRSTkFfc25uX3Jlcy4wLjIsIHNldS5xJHByZWRpY3RlZC5pZCkpCnByLnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUocHJvcC50YWJsZSh0YWJsZShzZXUucSRSTkFfc25uX3Jlcy4wLjIsIHNldS5xJHByZWRpY3RlZC5pZCkpKQp0LmxhYmxlcyRGcmVxIDwtIGFzLmRvdWJsZSh0LmxhYmxlcyRGcmVxKQoKCiMgdHJ5IGJhciBjaGFydApnZ3Bsb3QodC5sYWJsZXMsIGFlcyh5ID0gRnJlcSwgeCA9IFZhcjEsIGZpbGwgPSBWYXIyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ICJpZGVudGl0eSIpCgojIHNhdmUgb2piZWN0IHdpdGggcHJlZGljaXRvbnMKc2F2ZVJEUyhzZXUucSwgIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL1BoZW5vSUQvc2NSTkFzZXFTb3J0ZWQvb2Jqcy9OZXVyb25zRmlsdGVyZWRTZXUyODA5MjAyMi5SRFMiKQoKCgpgYGAKCmBgYHtyfQojIGNvbXBhcmUgdGhlIHRocmVlIHByZWRpY3Rpb25zCiNBU1QyMyB2cyBBSVc2MAp0LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJE1CT0FTVDIzLnByZWQsIHNldS5xJEFJVzYwLnByZWQpKQpwci50LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHByb3AudGFibGUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRwcmVkaWN0ZWQuaWQpKSkKdC5sYWJsZXMkRnJlcSA8LSBhcy5kb3VibGUodC5sYWJsZXMkRnJlcSkKCiMgdHJ5IGJhciBjaGFydApnZ3Bsb3QodC5sYWJsZXMsIGFlcyh5ID0gRnJlcSwgeCA9IFZhcjEsIGZpbGwgPSBWYXIyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ICJpZGVudGl0eSIpICsgUm90YXRlZEF4aXMoKQoKI0FTVDIzIHZzIEFJVzEyMAp0LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJE1CT0FTVDIzLnByZWQsIHNldS5xJE1CT0FJVy5wcmVkKSkKcHIudC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZShwcm9wLnRhYmxlKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuMiwgc2V1LnEkcHJlZGljdGVkLmlkKSkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCgojIHRyeSBiYXIgY2hhcnQKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKSArIFJvdGF0ZWRBeGlzKCkKCgojIEFJVzYwIHZzIEFJVzEyMAp0LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJEFJVzYwLnByZWQsIHNldS5xJE1CT0FJVy5wcmVkKSkKcHIudC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZShwcm9wLnRhYmxlKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuMiwgc2V1LnEkcHJlZGljdGVkLmlkKSkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCgojIHRyeSBiYXIgY2hhcnQKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKSArIFJvdGF0ZWRBeGlzKCkKCgpgYGAKClNlZSBob3cgZWFjaCBsb29rcyBvbiBVTUFQCgpgYGB7cn0KCkRpbVBsb3Qoc2V1LnEsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjEuMicpCkRpbVBsb3Qoc2V1LnEsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuMicpCkRpbVBsb3Qoc2V1LnEsIGdyb3VwLmJ5ID0gJ0FJVzYwLnByZWQnKQpEaW1QbG90KHNldS5xLCBncm91cC5ieSA9ICdNQk9BSVcucHJlZCcpCkRpbVBsb3Qoc2V1LnEsIGdyb3VwLmJ5ID0gJ01CT0FTVDIzLnByZWQnKQoKCmBgYAoKYGBge3J9CgojIHJlZG8gY2x1c3RlcnMKc2V1LnEgPC0gTm9ybWFsaXplRGF0YShzZXUucSwgbm9ybWFsaXphdGlvbi5tZXRob2QgPSAiTG9nTm9ybWFsaXplIiwgc2NhbGUuZmFjdG9yID0gMTAwMDApCnNldS5xIDwtIEZpbmRWYXJpYWJsZUZlYXR1cmVzKHNldS5xLCBzZWxlY3Rpb24ubWV0aG9kID0gInZzdCIsIG5mZWF0dXJlcyA9IDIwMDApCnNldS5xIDwtIFNjYWxlRGF0YShzZXUucSkKc2V1LnEgPC0gUnVuUENBKHNldS5xKQpzZXUucSA8LSBSdW5VTUFQKHNldS5xLCByZWR1Y3Rpb24gPSAicGNhIiwgbi5uZWlnaGJvcnMgPSAyNSwgZGltcyA9IDE6MzAsIG1pbi5kaXN0ID0gMC4yNSwgc3ByZWFkID0gMikKRGltUGxvdChzZXUucSwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICdNQk9BSVcucHJlZCcpCgoKCgoKYGBgCgoKUmVkbyBmaW5kIGNsdXN0ZXJzCgpgYGB7cn0KCnNldS5xIDwtIEZpbmROZWlnaGJvcnMoc2V1LnEsIGRpbXMgPSAxOjI1LCBrLnBhcmFtID0gNDMpCnNldS5xIDwtIEZpbmRDbHVzdGVycyhzZXUucSwgcmVzb2x1dGlvbiA9IGMoMCwwLjIsMC40LDAuNikpCnNldS5xIDwtIEZpbmRDbHVzdGVycyhzZXUucSwgcmVzb2x1dGlvbiA9IGMoMS4yKSkKCmxpYnJhcnkoY2x1c3RyZWUpCmNsdXN0cmVlKHNldS5xLCBwcmVmaXggPSAiUk5BX3Nubl9yZXMuIikKRGltUGxvdChzZXUucSkKYGBgCgpMb29rIGF0IHRoZSBwcmVkaWN0aW9ucyBpbiB0aGUgbmV3IGNsdXN0ZXJzCgpgYGB7cn0KIyBBSVcwMDIgMTYwIGRheXMgcHJlZGljdGlvbnMKdC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShzZXUucSRSTkFfc25uX3Jlcy4wLjYsIHNldS5xJE1CT0FJVy5wcmVkKSkKdC5sYWJsZXMkRnJlcSA8LSBhcy5kb3VibGUodC5sYWJsZXMkRnJlcSkKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKSArIFJvdGF0ZWRBeGlzKCkgCnRvcC5wcmVkLmNlbGx0eXBlLkFJVzEyMCA8LSBhcy5kYXRhLmZyYW1lKHQubGFibGVzICAlPiUgZ3JvdXBfYnkoVmFyMSkgICU+JSB0b3BfbigxLCBGcmVxKSkKCiMgQUlXMDAyIDE2MCBkYXlzIHByZWRpY3Rpb25zCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC42LCBzZXUucSRBSVc2MC5wcmVkKSkKdC5sYWJsZXMkRnJlcSA8LSBhcy5kb3VibGUodC5sYWJsZXMkRnJlcSkKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKSArIFJvdGF0ZWRBeGlzKCkgCnRvcC5wcmVkLmNlbGx0eXBlLkFJVzYwIDwtYXMuZGF0YS5mcmFtZSh0LmxhYmxlcyAgJT4lIGdyb3VwX2J5KFZhcjEpICAlPiUgdG9wX24oMSwgRnJlcSkpCgojIEFTVDIzIDY1IGRheXMgcHJlZGljdGlvbnMKdC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShzZXUucSRSTkFfc25uX3Jlcy4wLjYsIHNldS5xJE1CT0FTVDIzLnByZWQpKQp0LmxhYmxlcyRGcmVxIDwtIGFzLmRvdWJsZSh0LmxhYmxlcyRGcmVxKQpnZ3Bsb3QodC5sYWJsZXMsIGFlcyh5ID0gRnJlcSwgeCA9IFZhcjEsIGZpbGwgPSBWYXIyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ICJpZGVudGl0eSIpICsgUm90YXRlZEF4aXMoKSAKdG9wLnByZWQuY2VsbHR5cGUuQVNUMjMgPC0gYXMuZGF0YS5mcmFtZSh0LmxhYmxlcyAgJT4lIGdyb3VwX2J5KFZhcjEpICAlPiUgdG9wX24oMSwgRnJlcSkpCgoKcHJlZC50YWJsZSA8LSBtZXJnZSh0b3AucHJlZC5jZWxsdHlwZS5BSVcxMjAsdG9wLnByZWQuY2VsbHR5cGUuQUlXNjAsIGJ5ID0gJ1ZhcjEnKQpwcmVkLnRhYmxlIDwtIG1lcmdlKHByZWQudGFibGUsIHRvcC5wcmVkLmNlbGx0eXBlLkFTVDIzLCBieSA9ICdWYXIxJykKcHJlZC50YWJsZQoKYGBgCgpCYXNlZCBvbiB0aGUgMyBkaWZmZXJlbnQgcHJlZGljdGlvbnMgSSBjYW4gbGFibGUgdGhlIGNlbGwgdHlwZXMKCjAgLSBOUEMgb3IgZWFybHkgbmV1cm9ucwoxIC0gaW1tYXR1cmUgZXhjaXRhdG9yeSBuZXVyb25zCjIgLSBOUEMgb3IgZWFybHkgbmV1cm9ucwozIC0gUkcgb3IgT2xpZ29zCjQtIERvcGFtaW5lcmdpYyBuZXVyb25zIC0gcG9zc2libHkgZWFybHkKNSAtIE5QQyBvciBlYXJseSBuZXVyb25zCjYgLSBSYWRpYWwgR0xpYQoKSSB3aWxsIGFsc28gZmluZCBtYXJrZXJzIGFuZCBsb29rIGF0IGEgbGlzdCBvZiBuZXVyb25hbCBtYXJrZXJzCgpgYGB7cn0KCklkZW50cyhzZXUucSkgPC0gJ1JOQV9zbm5fcmVzLjAuNicKQ2x1c3Rlck1hcmtlcnMgPC0gRmluZEFsbE1hcmtlcnMoc2V1LnEsIG9ubHkucG9zID0gVFJVRSkKCnRvcDUgPC0gQ2x1c3Rlck1hcmtlcnMgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3BfbihuPTUsIHd0ID0gYXZnX2xvZzJGQykKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IHRvcDUkZ2VuZSwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjYnKQoKd3JpdGUuY3N2KENsdXN0ZXJNYXJrZXJzLCIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9QaGVub0lEL3NjUk5Bc2VxU29ydGVkL05ldXJvbnMxQ2x1c3Rlck1hcmtlcnM3LmNzdiIpCgoKYGBgCgpFeHBsb3JlIHNvbWUgR2VuZSBleHByZXNzaW9uIGxldmVscwoKYGBge3J9CmZlYXR1cmVfbGlzdCA9IGMoIk1LSTY3IiwiU09YMiIsIlBPVTVGMSIsIkRMWDIiLCJQQVg2IiwiU09YOSIsIkhFUzEiLCJORVMiLCJSQkZPWDMiLCJNQVAyIiwiTkNBTTEiLCJDRDI0IiwiR1JJQTIiLCJHUklOMkIiLCJHQUJCUjEiLCJHQUQxIiwiR0FEMiIsIkdBQlJBMSIsIkdBQlJCMiIsIlRIIiwiQUxESDFBMSIsIkxNWDFCIiwiTlI0QTIiLCJDT1JJTiIsIkNBTEIxIiwiS0NOSjYiLCJDWENSNCIsIklUR0E2IiwiU0xDMUEzIiwiQ0Q0NCIsIkFRUDQiLCJTMTAwQiIsICJQREdGUkEiLCJPTElHMiIsIk1CUCIsIkNMRE4xMSIsIlZJTSIsIlZDQU0xIikKCkRvSGVhdG1hcChzZXUucSwgZmVhdHVyZXMgPSBmZWF0dXJlX2xpc3QsIHNpemU9MywgYW5nbGUgPTkwLCBncm91cC5iYXIuaGVpZ2h0ID0gMC4wMiwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC42JykKRG90UGxvdChzZXUucSwgZmVhdHVyZXMgPSBmZWF0dXJlX2xpc3QpICtSb3RhdGVkQXhpcygpCgpQRF9wb3VsaW4gPSBjKCJUSCIsIlNMQzZBMyIsIlNMQzE4QTIiLCJTT1g2IiwiTkRORiIsIlNOQ0ciLCJBTERIMUExIiwiQ0FMQjEiLCJUQUNSMiIsIlNMQzE3QTYiLCJTTEMzMkExIiwiT1RYMiIsIkdSUCIsIkxQTCIsIkNDSyIsIlZJUCIpCgpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gUERfcG91bGluLCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuNicpCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gUERfcG91bGluKStSb3RhdGVkQXhpcygpCgplYWxyeU5ldXIgPSBjKCJEQ1giLCJORVVST0QxIiwiVEJSMSIpCnByb2xpZmVyYXRpb24gPSBjKCJQQ05BIiwiTUtJNjciKQpuZXVyYWxzdGVtID0gYygiU09YMiIsIk5FUyIsIlBBWDYiLCJNQVNIMSIpCgpmZWF0dXJlX2xpc3QgPC0gYygiRENYIiwiTkVVUk9EMSIsIlRCUjEiLCJQQ05BIiwiTUtJNjciLCJTT1gyIiwiTkVTIiwiUEFYNiIsIk1BU0gxIikKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IGZlYXR1cmVfbGlzdCwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjYnKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IGZlYXR1cmVfbGlzdCkrUm90YXRlZEF4aXMoKQojIG5vIHByb2xpZmVyYXRpb24gbWFya2VyIGV4cHJlc3Npb24gIFBDTkEgb3IgTUtJNjcKIyBjbHVzdGVyIDQgREEgbmV1cm9ucyAtIHNob3dzIGVhcmx5IG5ldXJvbiBtYXJrZXIgYW5kIGxvdyBQQVggNAojIGNsdXN0ZXIgMyBoYXMgaGlnaGVyIFNPWDIgLSBuZXVyb2JsYXN0IG1hcmtlciAvIE5QQyBtYXJrZXIKCm1hdF9uZXVyb24gPSBjKCJSQkZPWDMiLCJTWVAiLCJETEc0NSIsIlZBTVAxIiwiVkFNUDIiLCJUVUJCMyIsIlNZVDEiLCJCU04iLCJIT01FUjEiLCJTTEMxN0E2IikgCiMgTmV1TiBpcyBGT1gzIC0gUkJGT1gzCiMgUFNEOTUgYWxzbyBTUC05MCBvciBETEc0CiMgVkdMVVQyIGlzIFNMQzE3QTYKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IG1hdF9uZXVyb24sIHNpemU9MywgYW5nbGUgPTkwLCBncm91cC5iYXIuaGVpZ2h0ID0gMC4wMiwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC42JykKIyBjbHVzdGVyIDQgYWxzbyBzaG93IG1hdHVyZSBuZXVyb24gbWFya2VycwpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IG1hdF9uZXVyb24pK1JvdGF0ZWRBeGlzKCkKIyBleGNpdGF0b3J5IG5ldXJvbiBtYXJrZXJzCmV4ID0gYygiR1JJQTIiLCJHUklBMSIsIkdSSUE0IiwiR1JJTjEiLCJHUklOMkIiLCJHUklOMkEiLCJHUklOM0EiLCJHUklOMyIsIkdSSVAxIiwiQ0FNSzJBIikKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IGV4LCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuNicpCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gZXgpK1JvdGF0ZWRBeGlzKCkKIyBpbmhpYml0b3J5IG5ldXJvbiBtYXJrZXJzCmluaCA9IGMoIkdBRDEiLCJHQUQyIiwgIkdBVDEiLCJQVkFMQiIsIkdBQlIyIiwiR0FCUjEiLCJHQlJSMSIsIkdBQlJCMiIsIkdBQlJCMSIsIkdBQlJCMyIsIkdBQlJBNiIsIkdBQlJBMSIsIkdBQlJBNCIsIlRSQUsyIikKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IGluaCwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjYnKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IGluaCkrUm90YXRlZEF4aXMoKQojIGNsdXN0ZXIgNCBpcyBtb3JlIGV4Y2l0YXRvcnkgdGhhbiBpbmhiaXRvcnkgYnV0IG5laXRoZXIgbWFya2VyIHNldCBoYXMgbXVjaCBleHByZXNzaW9uIAoKCgpgYGAKCgpDaGVja291dCB0aGUgRW5yaWNoZXIgY2VsbCB0eXBlIGxpYnJhcmllcyBmcm9tIAoKYGBge3J9CiMgdGVzdCBtYXJrZXJzIGZvciB0aGUgNyBjbHVzdGVycyBpbiBOZXVyb25zMSAKCmxpYnJhcnkoZGV2dG9vbHMpCmluc3RhbGxfZ2l0aHViKCJ3amF3YWlkL2VucmljaFIiKQpsaWJyYXJ5KGVucmljaFIpCgoKc2V0RW5yaWNoclNpdGUoIkVucmljaHIiKSAjIEh1bWFuIGdlbmVzCiMgbGlzdCBvZiBhbGwgdGhlIGRhdGFiYXNlcwoKZGJzIDwtIGxpc3RFbnJpY2hyRGJzKCkKZGJzCiMgbGliYXJpZXMgd2l0aCBjZWxsIHR5cGVzCgpkYiA8LSBjKCdBbGxlbl9CcmFpbl9BdGxhc191cCcsJ0Rlc2NhcnRlc19DZWxsX1R5cGVzX2FuZF9UaXNzdWVfMjAyMScsCiAgICAgICAgJ0NlbGxNYXJrZXJfQXVnbWVudGVkXzIwMjEnLCdBemltdXRoX0NlbGxfVHlwZXNfMjAyMScpCgojIGVucmljaHIoZ2VuZXMsIGRhdGFiYXNlcyA9IE5VTEwpCgpOMS5jMCA8LSBDbHVzdGVyTWFya2VycyAlPiUgZmlsdGVyKGNsdXN0ZXIgPT0gMCAmIGF2Z19sb2cyRkMgPiAwKQpnZW5lcyA8LSBOMS5jMCRnZW5lCgpOMS5jMC5FciA8LSBlbnJpY2hyKGdlbmVzLCBkYXRhYmFzZXMgPSBkYikKcGxvdEVucmljaChOMS5jMC5FcltbMV1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jMC5FcltbMl1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jMC5FcltbM11dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKCk4xLkVyLmdlbmVzLjEgPC0gTjEuYzAuRXJbWzFdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMQoKTjEuRXIuZ2VuZXMuMiA8LSBOMS5jMC5FcltbMl1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4yCgpOMS5Fci5nZW5lcy4zIDwtIE4xLmMwLkVyW1szXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjMKCiMgY2x1c3RlciAwIGNvdWxkIGJlIGh5cG90aGFsbXVzLCBEQSBuZXVyb25zIEExMwoKTjEuYzEgPC0gQ2x1c3Rlck1hcmtlcnMgJT4lIGZpbHRlcihjbHVzdGVyID09IDEgJiBhdmdfbG9nMkZDID4gMCkKZ2VuZXMgPC0gTjEuYzEkZ2VuZQoKTjEuYzEuRXIgPC0gZW5yaWNocihnZW5lcywgZGF0YWJhc2VzID0gZGIpCnBsb3RFbnJpY2goTjEuYzEuRXJbWzFdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzEuRXJbWzJdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzEuRXJbWzNdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzEuRXJbWzRdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCgpOMS5Fci5nZW5lcy4xIDwtIE4xLmMxLkVyW1sxXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjEKCk4xLkVyLmdlbmVzLjIgPC0gTjEuYzEuRXJbWzJdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMgoKTjEuRXIuZ2VuZXMuMyA8LSBOMS5jMS5FcltbM11dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4zCgpOMS5Fci5nZW5lcy40IDwtIE4xLmMxLkVyW1s0XV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjQKCiMgY2x1c3RlciAxOyBvbGZhY3RvcnkgYnVsYiwgbmV1cmFsIHBsYXRlLCBtYXliZSBSYWRpYWwgR2xpYSwgCk4xLmMyIDwtIENsdXN0ZXJNYXJrZXJzICU+JSBmaWx0ZXIoY2x1c3RlciA9PSAyICYgYXZnX2xvZzJGQyA+IDApCmdlbmVzIDwtIE4xLmMyJGdlbmUKCk4xLmMyLkVyIDwtIGVucmljaHIoZ2VuZXMsIGRhdGFiYXNlcyA9IGRiKQpwbG90RW5yaWNoKE4xLmMyLkVyW1sxXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmMyLkVyW1syXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmMyLkVyW1szXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmMyLkVyW1s0XV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQoKTjEuRXIuZ2VuZXMuMSA8LSBOMS5jMi5FcltbMV1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4xCgpOMS5Fci5nZW5lcy4yIDwtIE4xLmMyLkVyW1syXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjIKCk4xLkVyLmdlbmVzLjMgPC0gTjEuYzIuRXJbWzNdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMwoKTjEuRXIuZ2VuZXMuNCA8LSBOMS5jMi5FcltbNF1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy40CgojIGNsdXN0ZXIgMiBzb21lIGJyYWluIG51Y2xldXMsIG5ldXJhbCBzdGVtCgpOMS5jMyA8LSBDbHVzdGVyTWFya2VycyAlPiUgZmlsdGVyKGNsdXN0ZXIgPT0gMyAmIGF2Z19sb2cyRkMgPiAwKQpnZW5lcyA8LSBOMS5jMyRnZW5lCgpOMS5jMy5FciA8LSBlbnJpY2hyKGdlbmVzLCBkYXRhYmFzZXMgPSBkYikKcGxvdEVucmljaChOMS5jMy5FcltbMV1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jMy5FcltbMl1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jMy5FcltbM11dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jMy5FcltbNF1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKCk4xLkVyLmdlbmVzLjEgPC0gTjEuYzMuRXJbWzFdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMQoKTjEuRXIuZ2VuZXMuMiA8LSBOMS5jMy5FcltbMl1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4yCgpOMS5Fci5nZW5lcy4zIDwtIE4xLmMzLkVyW1szXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjMKCk4xLkVyLmdlbmVzLjQgPC0gTjEuYzMuRXJbWzRdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuNAoKIyBjbHVzdGVyIDMgc3Ryb21hbCBjZWxsIG9mIHRoeW11cywgZW1icnlvbmljIGFzdHJvY3l0ZXMsIE9QQywgTksgY2VsbHMsIG1vbm9jeXRlcwoKTjEuYzQgPC0gQ2x1c3Rlck1hcmtlcnMgJT4lIGZpbHRlcihjbHVzdGVyID09IDQgJiBhdmdfbG9nMkZDID4gMCkKZ2VuZXMgPC0gTjEuYzQkZ2VuZQoKTjEuYzQuRXIgPC0gZW5yaWNocihnZW5lcywgZGF0YWJhc2VzID0gZGIpCnBsb3RFbnJpY2goTjEuYzQuRXJbWzFdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzQuRXJbWzJdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzQuRXJbWzNdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzQuRXJbWzRdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCgpOMS5Fci5nZW5lcy4xIDwtIE4xLmM0LkVyW1sxXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjEKCk4xLkVyLmdlbmVzLjIgPC0gTjEuYzQuRXJbWzJdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMgoKTjEuRXIuZ2VuZXMuMyA8LSBOMS5jNC5FcltbM11dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4zCgpOMS5Fci5nZW5lcy40IDwtIE4xLmM0LkVyW1s0XV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjQKCiMgRGVudGF0ZSBneXJ1cyAtIGRpZmZlcmVudCBjb3J0aWNhbCBsYXllcnMsIG5ldXJvbnMsIG5ldXJvbnMsIE5QQywgbmV1cm9ucyBHQUJBLEdMVVQKCk4xLmM1IDwtIENsdXN0ZXJNYXJrZXJzICU+JSBmaWx0ZXIoY2x1c3RlciA9PSA1ICYgYXZnX2xvZzJGQyA+IDApCmdlbmVzIDwtIE4xLmM1JGdlbmUKCk4xLmM1LkVyIDwtIGVucmljaHIoZ2VuZXMsIGRhdGFiYXNlcyA9IGRiKQpwbG90RW5yaWNoKE4xLmM1LkVyW1sxXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmM1LkVyW1syXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmM1LkVyW1szXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmM1LkVyW1s0XV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQoKTjEuRXIuZ2VuZXMuMSA8LSBOMS5jNS5FcltbMV1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4xCgpOMS5Fci5nZW5lcy4yIDwtIE4xLmM1LkVyW1syXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjIKCk4xLkVyLmdlbmVzLjMgPC0gTjEuYzUuRXJbWzNdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMwoKTjEuRXIuZ2VuZXMuNCA8LSBOMS5jNS5FcltbNF1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy40CgojIGNsdXN0ZXIgNSBoaXBwb2NhbXB1cywgZW5kb3RoZWxpYWwgY2VsbHMsIHBlcmljeXRlcwoKTjEuYzYgPC0gQ2x1c3Rlck1hcmtlcnMgJT4lIGZpbHRlcihjbHVzdGVyID09IDYgJiBhdmdfbG9nMkZDID4gMCkKZ2VuZXMgPC0gTjEuYzYkZ2VuZQoKTjEuYzYuRXIgPC0gZW5yaWNocihnZW5lcywgZGF0YWJhc2VzID0gZGIpCnBsb3RFbnJpY2goTjEuYzYuRXJbWzFdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzYuRXJbWzJdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzYuRXJbWzNdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzYuRXJbWzRdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCgpOMS5Fci5nZW5lcy4xIDwtIE4xLmM2LkVyW1sxXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjEKCk4xLkVyLmdlbmVzLjIgPC0gTjEuYzYuRXJbWzJdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMgoKTjEuRXIuZ2VuZXMuMyA8LSBOMS5jNi5FcltbM11dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4zCgpOMS5Fci5nZW5lcy40IDwtIE4xLmM2LkVyW1s0XV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjQKCiMgY2x1c3RlciA2IGJyYWluIGNvcnRleCwgc2h3YW5uIGNlbGwsIGVuZG90aGVsaWFsLCBwZXJpY3l0ZSwgR0FCQQoKCmBgYAoKTGlicmFyeSBvZiB0aXNzdWUgY2VsbCB0eXBlcyBmb3IgdXAgcmVndWxhdGVkIGdlbmVzIHBlciBjbHVzdGVyCjAgLSBoeXBvdGhhbG11cywgREEgQTEzCjEtIG5ldXJhbCBwbGF0ZSwgUmFkaWFsIEdsaWEKMiAtIE5ldXJhbCBzdGVtCjMgLSBzdHJvbWFsLCBhc3RybyBPUEMKNCAtIE5ldXJvbnMKNSAtIGVuZG90aGVsaWFsLCBwZXJpY3l0ZQo2IC0gbWF5YmUgbmV1cm9ucyBtYXliZSBub3QKCgpCeSB0aGUgY29tYmluZWQgaW5mb3JtYXRpb24gLSBhbm5vdGF0ZSB0aGUgY2x1c3RlcnMgaW4gTmV1cm9uczEKCmBgYHtyfQojQmFzZWQgb24gdGhlIDMgZGlmZmVyZW50IHByZWRpY3Rpb25zIEkgY2FuIGxhYmxlIHRoZSBjZWxsIHR5cGVzCgojMCAtIE5QQyBvciBlYXJseSBuZXVyb25zCiMxIC0gaW1tYXR1cmUgZXhjaXRhdG9yeSBuZXVyb25zCiMyIC0gTlBDIG9yIGVhcmx5IG5ldXJvbnMKIzMgLSBSRyBvciBPbGlnb3MKIzQtIERvcGFtaW5lcmdpYyBuZXVyb25zIC0gcG9zc2libHkgZWFybHkKIzUgLSBOUEMgb3IgZWFybHkgbmV1cm9ucwojNiAtIFJhZGlhbCBHbGlhCgpJZGVudHMoc2V1LnEpIDwtICdSTkFfc25uX3Jlcy4wLjYnCmNsdXN0ZXIuaWRzIDwtIGMoIkltbWF0dXJlTmV1cm9ucyIsIk5ldXJvbnMiLCJOUEMiLCJPUEMtUkciLCJEQW5ldXJvbnMiLAogICAgICAgICAgICAgICAgICJPdGhlciIsIlJHIikKdW5pcXVlKHNldS5xJFJOQV9zbm5fcmVzLjAuNikKCm5hbWVzKGNsdXN0ZXIuaWRzKSA8LSBsZXZlbHMoc2V1LnEpCnNldS5xIDwtIFJlbmFtZUlkZW50cyhzZXUucSwgY2x1c3Rlci5pZHMpCnNldS5xJHN1Ymdyb3VwcyA8LSBJZGVudHMoc2V1LnEpCgpEaW1QbG90KHNldS5xLCByZWR1Y3Rpb24gPSAidW1hcCIsIGxhYmVsID0gVFJVRSwgZ3JvdXAuYnkgPSAnc3ViZ3JvdXBzJywgcmVwZWwgPSBUUlVFKQoKCnNhdmVSRFMoc2V1LnEsICIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9QaGVub0lEL3NjUk5Bc2VxU29ydGVkL29ianMvTmV1cm9uMUxhYmxlZFNldTMwMDkyMDIyLlJEUyIpCgpgYGAKCgojIyMgTmV4dCBSZXBlYXQgZXZlcnl0aGluZyBmb3IgTmV1cm9uczIKCmBgYHtyfQojIGV4cGxvcmUgZmlsdGVyaW5nCnNldSA8LSBOZXVyb25zMgpzZXUKVmxuUGxvdChzZXUsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIsICJuQ291bnRfUk5BIiwgInBlcmNlbnQubXQiKSwgbmNvbCA9IDMpCgpWbG5QbG90KHNldSwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiksIHkubWF4ID0gMjAwMCkKVmxuUGxvdChzZXUsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIpLCB5Lm1heCA9IDM1MCkKVmxuUGxvdChzZXUsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5Db3VudF9STkEiKSwgeS5tYXggPSAyMDAwKQoKIyBmaWx0ZXIgbW9yZSBjZWxscwoKc2V1LmZ0IDwtIHN1YnNldChzZXUsIHN1YnNldCA9IG5GZWF0dXJlX1JOQSA+IDMwMCAmIG5Db3VudF9STkEgPiA1MDAgJiBuQ291bnRfUk5BIDwgMTAwMDApIApzZXUuZnQKCiMgMTc2MDQgc2FtcGxlcyB3aXRoIDI1MCBuRmVhdHVyZV9STkEKIyA5NjU3IHdpdGggIG5GZWF0dXJlIDMwMCBhbmQgbkNPdW50IDUwMAoKCmBgYAoKCkRvdWJsZXQgZmluZGVyIAoKYGBge3J9CnN1cHByZXNzTWVzc2FnZXMocmVxdWlyZShEb3VibGV0RmluZGVyKSkKCiMgZmlsdGVyaW5nIG91dCBNQUxBVDEgYW5kIG1pdG9jaG9uZHJpYWwgZ2VuZXMKCnNldS5mdCA8LSBzZXUuZnRbIWdyZXBsKCJNQUxBVDEiLCByb3duYW1lcyhzZXUpKSwgXQpzZXUuZnQgPC0gc2V1LmZ0WyFncmVwbCgiXk1ULSIsIHJvd25hbWVzKHNldS5mdCkpLCBdCgojIGxpa2UgaW4gdGhlIHR1dG9yaWFsIEknbSBmb2xsb3dpbmcgTUFMQVQxIGlzIHRoZSB0b3AgbW9zdCBleHByZXNzZWQgZ2VuZS4gIFRoZSB0b3AgZ2VuZXMgYXJlIGEgbG90IG9mIE1UIGFuZCBSaWJvc29tYWwgZ2VuZXMKCnNldS5mdFtbInBlcmNlbnQucmIiXV0gPC0gUGVyY2VudGFnZUZlYXR1cmVTZXQoc2V1LmZ0LCBwYXR0ZXJuID0gIl5SUCIpCgpzZXUuZCA9IE5vcm1hbGl6ZURhdGEoc2V1LmZ0KQpzZXUuZCA9IEZpbmRWYXJpYWJsZUZlYXR1cmVzKHNldS5kLCB2ZXJib3NlID0gRikKc2V1LmQgPSBTY2FsZURhdGEoc2V1LmQsIHZhcnMudG8ucmVncmVzcyA9IGMoIm5GZWF0dXJlX1JOQSIsICJwZXJjZW50Lm10IiksCiAgICB2ZXJib3NlID0gRikKc2V1LmQgPSBSdW5QQ0Eoc2V1LmQsIHZlcmJvc2UgPSBGLCBucGNzID0gMzApCnNldS5kID0gUnVuVU1BUChzZXUuZCwgZGltcyA9IDE6MTAsIHZlcmJvc2UgPSBGKQoKbkV4cCA8LSByb3VuZChuY29sKHNldS5kKSAqIDAuMDgpICAjIGV4cGVjdCBtb3JlIGRvdWJsZXRzIGJlY2F1c2UgdGhlcmUgaXMgYSBsb3QgbW9yZSBjZWxscwpzZXUuZCA8LSBkb3VibGV0RmluZGVyX3YzKHNldS5kLCBwTiA9IDAuMjUsIHBLID0gMC4wOSwgbkV4cCA9IG5FeHAsIFBDcyA9IDE6MTApCgoKIyBuYW1lIG9mIHRoZSBERiBwcmVkaWN0aW9uIGNhbiBjaGFuZ2UsIHNvIGV4dHJhY3QgdGhlIGNvcnJlY3QgY29sdW1uIG5hbWUuCkRGLm5hbWUgPSBjb2xuYW1lcyhzZXUuZEBtZXRhLmRhdGEpW2dyZXBsKCJERi5jbGFzc2lmaWNhdGlvbiIsIGNvbG5hbWVzKHNldS5kQG1ldGEuZGF0YSkpXQoKCmNvd3Bsb3Q6OnBsb3RfZ3JpZChuY29sID0gMiwgRGltUGxvdChzZXUuZCwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpICsgTm9BeGVzKCksCiAgICBEaW1QbG90KHNldS5kLCBncm91cC5ieSA9IERGLm5hbWUpICsgTm9BeGVzKCkpCgpWbG5QbG90KHNldS5kLCBmZWF0dXJlcyA9ICJuRmVhdHVyZV9STkEiLCBncm91cC5ieSA9IERGLm5hbWUsIHB0LnNpemUgPSAwLjEpCgpgYGAKCgpSZW1vdmUgdGhlIGRvdWJsZXQgY2VsbHMKCmBgYHtyfQoKc2V1LmQgPC0gc2V1LmRbLCBzZXUuZEBtZXRhLmRhdGFbLCBERi5uYW1lXT09ICJTaW5nbGV0Il0KZGltKHNldS5kKQpkaW0oc2V1KQojIDk2NTcgY2VsbHMgcHJlIGZpbHRlcgojIDg4ODQgY2VsbHMgYWZ0ZXIgZmlsdGVyaW5nCiMgbm90ZSB0aGUgcGVyY2VudCBkb3VibGVzIGV4cGVjdGVkIGlzIGNsb3NlIHRvIHRoZSBwZXJjZW50IGRldGVjdGVkCgpgYGAKCgpSZXBlYXQgd29ya2Zsb3cgd2l0aCBkb3VibGV0IHJlbW92ZWQgZGF0YSBhbmQgZmluZCBjbHVzdGVycyBmb3IgCgpgYGB7cn0KCgpzZXUgPC0gTm9ybWFsaXplRGF0YShzZXUuZCwgbm9ybWFsaXphdGlvbi5tZXRob2QgPSAiTG9nTm9ybWFsaXplIiwgc2NhbGUuZmFjdG9yID0gMTAwMDApCnNldSA8LSBGaW5kVmFyaWFibGVGZWF0dXJlcyhzZXUsIHNlbGVjdGlvbi5tZXRob2QgPSAidnN0IiwgbmZlYXR1cmVzID0gMjAwMCkKc2V1IDwtIFNjYWxlRGF0YShzZXUpCnNldSA8LSBSdW5QQ0Eoc2V1KQpzZXUgPC0gUnVuVU1BUChzZXUsIHJlZHVjdGlvbiA9ICJwY2EiLCBuLm5laWdoYm9ycyA9IDQzLCBkaW1zID0gMTozMCkKRGltUGxvdChzZXUsIHJlZHVjdGlvbiA9ICJ1bWFwIikKCnNldS5xIDwtIEZpbmROZWlnaGJvcnMoc2V1LCBkaW1zID0gMToyNSwgay5wYXJhbSA9IDQzKQpzZXUucSA8LSBGaW5kQ2x1c3RlcnMoc2V1LnEsIHJlc29sdXRpb24gPSBjKDAsMC4yLDAuNCwwLjYpKQoKbGlicmFyeShjbHVzdHJlZSkKY2x1c3RyZWUoc2V1LnEpCgpEaW1QbG90KHNldS5xLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuMicpCkRpbVBsb3Qoc2V1LnEsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC40JykKRGltUGxvdChzZXUucSwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjYnKQpEaW1QbG90KHNldS5xLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjEuMicpCgpgYGAKCkxhYmVsIGNlbGwgdHlwZXMgdXNpbmcgdGhlIGxhYmVsIHRyYW5zZmVyCgpgYGB7cn0KCgoKIyBTTkNBIGFuZCBjb250cm9sIG1pZGJyYWluIG9yZ2Fub2lkcyAxNjUgZGF5cyBpbiBjdWx0dXJlCk1CTyA8LSByZWFkUkRTKCIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9BU1QyM19CcmFpbkNvbW0vTUJPY2x1c3RlcnNfbmFtZXMyOTA3MjAyMS5yZHMiKQoKIyBNaWRicmFpbiAgQUlXMDAyIDEyMCBkYXlzIGluIGN1bHR1cmUKQUlXTUJPIDwtIHJlYWRSRFMoIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL0FJV3RyaW8xMjBkYXlzL01PaW50ZWdyYXRlZENsdXN0ZXJLMTIzcmVzMC44Lm5hbWVzX25vdjE2XzIwMjEiKQoKIyBNaWRicmFpbiBBSVcwMDIgNjAgZGF5cyBpbiBjdWx0dXJlCgpBSVc2MCA8LSByZWFkUkRTKCIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9BSVd0cmlvNjBkYXlzL0FXSTAwMlBhcmtpbktPUGlua0tPNjBkYXlzX2xhYmVsc18xNDA1MjAyMi5yZHMiKQoKCiMgcXVlcnkKI3NldS5xIDwtIHJlYWRSRFMoIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL1BoZW5vSUQvc2NSTkFzZXFTb3J0ZWQvb2Jqcy9OZXVyb25zRmlsdGVyZWRTZXUyODA5MjAyMi5SRFMiKQoKCiNmaXJzdCBwcmVkaWN0IHdpdGggdGhlIE1CTyBkYXRhCklkZW50cyhNQk8pIDwtICJjbHVzdGVyX2xhYmVscyIKRGVmYXVsdEFzc2F5KE1CTykgPC0gIlJOQSIKCiMgZmluZCB0aGUgcmVmZXJlbmNlIGFuY2hvcnMKcHJpbnQoImZpbmRpbmcgcmVmZXJlbmNlIGFuY2hvcnMiKQphbmNob3JzIDwtIEZpbmRUcmFuc2ZlckFuY2hvcnMocmVmZXJlbmNlID0gTUJPICxxdWVyeSA9IHNldS5xLCBkaW1zID0gMToyNSkKcHJpbnQoImdldHRpbmcgcHJlZGljdGlvbnMiKQpwcmVkaWN0aW9ucyA8LSBUcmFuc2ZlckRhdGEoYW5jaG9yc2V0ID0gYW5jaG9ycywgcmVmZGF0YSA9IE1CTyRjbHVzdGVyX2xhYmVscykKc2V1LnEgPC0gQWRkTWV0YURhdGEoc2V1LnEsIG1ldGFkYXRhID0gcHJlZGljdGlvbnMpCnByaW50KHRhYmxlKHNldS5xJHByZWRpY3RlZC5pZCkpCgpJZGVudHMoc2V1LnEpIDwtICdwcmVkaWN0ZWQuaWQnCiMgYWRkIG5ldyBkYXRhc2xvdCBmb3IgTUJPIHByZWRpY3RlZCBJRCB0byBtYWtlIHRoZSBuZXh0IHByZWRpY3Rpb24Kc2V1LnEkTUJPQVNUMjMucHJlZCA8LSBJZGVudHMoc2V1LnEpCkRpbVBsb3Qoc2V1LnEsIGdyb3VwLmJ5ID0gJ01CT0FTVDIzLnByZWQnLCBsYWJlbCA9IFRSVUUpCiAKIyMgY2hlY2sgdGhlIHByb3BvcnRpb24gb2YgY2VsbCB0eXBlcyBwcmVkaWN0ZWQgaW4gZWFjaCBjbHVzdGVyCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRwcmVkaWN0ZWQuaWQpKQpwci50LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHByb3AudGFibGUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRwcmVkaWN0ZWQuaWQpKSkKdC5sYWJsZXMkRnJlcSA8LSBhcy5kb3VibGUodC5sYWJsZXMkRnJlcSkKCgojIHRyeSBiYXIgY2hhcnQKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKQoKIyBjbHVzdGVycyBkb24ndCBicmVhayB1cCBieSB0aGUgcHJlZGljdGVkIGNlbGwgdHlwZXMKCiMjIyMjIyMjIyMjIyBhbm90aGVyIHByZWRpY3Rpb25zIG5vdyB1c2luZyB0aGUgQUlXIG9yZ2Fub2lkcwoKSWRlbnRzKEFJV01CTykgPC0gInJlczA4bmFtZXMiCkRlZmF1bHRBc3NheShBSVdNQk8pIDwtICJSTkEiCgphbmNob3JzIDwtIEZpbmRUcmFuc2ZlckFuY2hvcnMocmVmZXJlbmNlID0gQUlXTUJPICxxdWVyeSA9IHNldS5xLCBkaW1zID0gMToyNSkKcHJpbnQoImdldHRpbmcgcHJlZGljdGlvbnMiKQpwcmVkaWN0aW9ucyA8LSBUcmFuc2ZlckRhdGEoYW5jaG9yc2V0ID0gYW5jaG9ycywgcmVmZGF0YSA9IEFJV01CTyRyZXMwOG5hbWVzKQpzZXUucSA8LSBBZGRNZXRhRGF0YShzZXUucSwgbWV0YWRhdGEgPSBwcmVkaWN0aW9ucykKcHJpbnQodGFibGUoc2V1LnEkcHJlZGljdGVkLmlkKSkKCklkZW50cyhzZXUucSkgPC0gJ3ByZWRpY3RlZC5pZCcKIyBhZGQgbmV3IGRhdGFzbG90IGZvciBNQk8gcHJlZGljdGVkIElEIHRvIG1ha2UgdGhlIG5leHQgcHJlZGljdGlvbgpzZXUucSRNQk9BSVcucHJlZCA8LSBJZGVudHMoc2V1LnEpCkRpbVBsb3Qoc2V1LnEsIGdyb3VwLmJ5ID0gJ01CT0FJVy5wcmVkJywgbGFiZWwgPSBUUlVFKQogCiMjIGNoZWNrIHRoZSBwcm9wb3J0aW9uIG9mIGNlbGwgdHlwZXMgcHJlZGljdGVkIGluIGVhY2ggY2x1c3Rlcgp0LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuMiwgc2V1LnEkcHJlZGljdGVkLmlkKSkKcHIudC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZShwcm9wLnRhYmxlKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuMiwgc2V1LnEkcHJlZGljdGVkLmlkKSkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCgoKIyB0cnkgYmFyIGNoYXJ0CmdncGxvdCh0LmxhYmxlcywgYWVzKHkgPSBGcmVxLCB4ID0gVmFyMSwgZmlsbCA9IFZhcjIpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdD0gImlkZW50aXR5IikKCiMgdGhlIHByZWRpY3RlZCBjZWxsIHR5cGVzIG1ha2UgbW9yZSBzZW5zZSBmcm9tIHRoZSBBSVcwMDIgb3JnYW5vaWQKIyBub3cgcHJlZGljdCB3aXRoIHRoZSBBSVcwMDIgNjAgZGF5cyBvcmdhbm9pZAoKSWRlbnRzKEFJVzYwKSA8LSAiY2x1c3Rlci5pZHMiCkRlZmF1bHRBc3NheShBSVc2MCkgPC0gIlJOQSIKCmFuY2hvcnMgPC0gRmluZFRyYW5zZmVyQW5jaG9ycyhyZWZlcmVuY2UgPSBBSVc2MCwgcXVlcnkgPSBzZXUucSwgZGltcyA9IDE6MjUpCnByaW50KCJnZXR0aW5nIHByZWRpY3Rpb25zIikKcHJlZGljdGlvbnMgPC0gVHJhbnNmZXJEYXRhKGFuY2hvcnNldCA9IGFuY2hvcnMsIHJlZmRhdGEgPSBBSVc2MCRjbHVzdGVyLmlkcykgCnNldS5xIDwtIEFkZE1ldGFEYXRhKHNldS5xLCBtZXRhZGF0YSA9IHByZWRpY3Rpb25zKQpwcmludCh0YWJsZShzZXUucSRwcmVkaWN0ZWQuaWQpKQoKSWRlbnRzKHNldS5xKSA8LSAncHJlZGljdGVkLmlkJwojIGFkZCBuZXcgZGF0YXNsb3QgZm9yIE1CTyBwcmVkaWN0ZWQgSUQgdG8gbWFrZSB0aGUgbmV4dCBwcmVkaWN0aW9uCnNldS5xJEFJVzYwLnByZWQgPC0gSWRlbnRzKHNldS5xKQpEaW1QbG90KHNldS5xLCBncm91cC5ieSA9ICdBSVc2MC5wcmVkJywgbGFiZWwgPSBUUlVFKQogCiMjIGNoZWNrIHRoZSBwcm9wb3J0aW9uIG9mIGNlbGwgdHlwZXMgcHJlZGljdGVkIGluIGVhY2ggY2x1c3Rlcgp0LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuMiwgc2V1LnEkcHJlZGljdGVkLmlkKSkKcHIudC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZShwcm9wLnRhYmxlKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuMiwgc2V1LnEkcHJlZGljdGVkLmlkKSkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCgoKIyB0cnkgYmFyIGNoYXJ0CmdncGxvdCh0LmxhYmxlcywgYWVzKHkgPSBGcmVxLCB4ID0gVmFyMSwgZmlsbCA9IFZhcjIpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdD0gImlkZW50aXR5IikKCiMgc2F2ZSBvamJlY3Qgd2l0aCBwcmVkaWNpdG9ucwpzYXZlUkRTKHNldS5xLCAiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvUGhlbm9JRC9zY1JOQXNlcVNvcnRlZC9vYmpzL05ldXJvbnMyUHJlZGljdGlvbnNTZXUzMDA5MjAyMi5SRFMiKQoKCgpgYGAKClNlZSB0aGUgdG9wIHByZWRpY3Rpb25zIGZvciBlYWNoIGNsdXN0ZXIgaW4gTmV1cm9uczIgcmVzIDA2IAoKCmBgYHtyfQoKIyBBSVcwMDIgMTIwIGRheXMgcHJlZGljdGlvbnMKdC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShzZXUucSRSTkFfc25uX3Jlcy4wLjYsIHNldS5xJE1CT0FJVy5wcmVkKSkKdC5sYWJsZXMkRnJlcSA8LSBhcy5kb3VibGUodC5sYWJsZXMkRnJlcSkKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKSArIFJvdGF0ZWRBeGlzKCkgCnRvcC5wcmVkLmNlbGx0eXBlLkFJVzEyMCA8LSBhcy5kYXRhLmZyYW1lKHQubGFibGVzICAlPiUgZ3JvdXBfYnkoVmFyMSkgICU+JSB0b3BfbigyLCBGcmVxKSkKZGYudG9wLmFpdzEyMCA8LSB0b3AucHJlZC5jZWxsdHlwZS5BSVcxMjBbb3JkZXIodG9wLnByZWQuY2VsbHR5cGUuQUlXMTIwJFZhcjEsLXRvcC5wcmVkLmNlbGx0eXBlLkFJVzEyMCRGcmVxKSxdCnJvdy5uYW1lcyhkZi50b3AuYWl3MTIwKSA8LSBOVUxMCmRmLnRvcC5haXcxMjAkSSA8LSByb3cubmFtZXMoZGYudG9wLmFpdzEyMCkKCiMgQUlXMDAyIDYwIGRheXMgcHJlZGljdGlvbnMKdC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShzZXUucSRSTkFfc25uX3Jlcy4wLjYsIHNldS5xJEFJVzYwLnByZWQpKQp0LmxhYmxlcyRGcmVxIDwtIGFzLmRvdWJsZSh0LmxhYmxlcyRGcmVxKQpnZ3Bsb3QodC5sYWJsZXMsIGFlcyh5ID0gRnJlcSwgeCA9IFZhcjEsIGZpbGwgPSBWYXIyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ICJpZGVudGl0eSIpICsgUm90YXRlZEF4aXMoKSAKdG9wLnByZWQuY2VsbHR5cGUuQUlXNjAgPC1hcy5kYXRhLmZyYW1lKHQubGFibGVzICAlPiUgZ3JvdXBfYnkoVmFyMSkgICU+JSB0b3BfbigyLCBGcmVxKSkKZGYudG9wLmFpdzYwIDwtIHRvcC5wcmVkLmNlbGx0eXBlLkFJVzYwW29yZGVyKHRvcC5wcmVkLmNlbGx0eXBlLkFJVzYwJFZhcjEsLXRvcC5wcmVkLmNlbGx0eXBlLkFJVzYwJEZyZXEpLF0Kcm93Lm5hbWVzKGRmLnRvcC5haXc2MCkgPC0gTlVMTApkZi50b3AuYWl3NjAkSSA8LSByb3cubmFtZXMoZGYudG9wLmFpdzYwKQoKCiMgQVNUMjMgMTY1IGRheXMgcHJlZGljdGlvbnMKdC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShzZXUucSRSTkFfc25uX3Jlcy4wLjYsIHNldS5xJE1CT0FTVDIzLnByZWQpKQp0LmxhYmxlcyRGcmVxIDwtIGFzLmRvdWJsZSh0LmxhYmxlcyRGcmVxKQpnZ3Bsb3QodC5sYWJsZXMsIGFlcyh5ID0gRnJlcSwgeCA9IFZhcjEsIGZpbGwgPSBWYXIyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ICJpZGVudGl0eSIpICsgUm90YXRlZEF4aXMoKSAKdG9wLnByZWQuY2VsbHR5cGUuQVNUMjMgPC0gYXMuZGF0YS5mcmFtZSh0LmxhYmxlcyAgJT4lIGdyb3VwX2J5KFZhcjEpICAlPiUgdG9wX24oMiwgRnJlcSkpCmRmLnRvcC5BU1QyMyA8LSB0b3AucHJlZC5jZWxsdHlwZS5BU1QyM1tvcmRlcih0b3AucHJlZC5jZWxsdHlwZS5BU1QyMyRWYXIxLC10b3AucHJlZC5jZWxsdHlwZS5BU1QyMyRGcmVxKSxdCnJvdy5uYW1lcyhkZi50b3AuQVNUMjMpIDwtIE5VTEwKZGYudG9wLkFTVDIzJEkgPC0gcm93Lm5hbWVzKGRmLnRvcC5BU1QyMykKCnByZWQudGFibGUgPC0gbWVyZ2UoZGYudG9wLkFTVDIzLCBkZi50b3AuYWl3NjAsIGJ5ID0gJ0knLCBhbGwgPSBUUlVFKQpwcmVkLnRhYmxlIDwtIG1lcmdlKHByZWQudGFibGUsIGRmLnRvcC5haXcxMjAsIGJ5ID0gJ0knKQpwcmVkLnRhYmxlCgpgYGAKCldoYXQgY2VsbCB0eXBlcyBhcmUgcHJlZGljdGVkIGFjcm9zcyB0aGUgMyByZWZlcmVuY2VzCgowIC0gTmV1cm9ucyBlYXJseSAsIE5QQywgbmV1cm9ucyBleGNpdGF0b3J5CjEgLSBOZXVyb25zIGVhcmx5LCBOUEMKMiAtIE5ldXJvbnMgZWFybHksIE5QQywgbmV1cm9ucyBleGNpdGF0b3J5IHNvbWUgREEgbmV1cm9ucwozIC0gT2xpZ28sIFJHLCAKNCAtIEV4Y2l0YXRvcnkgbmV1cm9ucywgTlBDLCBlYXJseSBuZXVyb25zCjUgLSBEQSBuZXVyb25zLCBlYXJseSBEQSBuZXVyb25zCjYgLSBuZXVyb25zIGltbWF0dXJlIE5QQwo3IC0gREEgbmV1cm9ucwo4IC0gUkcsIG9saWdvLCBPUEMsIE5QQwo5IC0gUmFkaWFsIEdsaWEKMTAgLSBOUEMsIG5ldXJvbnMsIG9saWdvCjExIC0gTlBDLCBuZXVyb25zLCBvbGlnbwoKCkZpbmQgY2x1c3RlciBtYXJrZXJzIGFuZCBzZWUgaG93IHRob3NlIHdvdWxkIGFubm90YXRlCgpgYGB7cn0KSWRlbnRzKHNldS5xKSA8LSAnUk5BX3Nubl9yZXMuMC42JwpDbHVzdGVyTWFya2VycyA8LSBGaW5kQWxsTWFya2VycyhzZXUucSwgb25seS5wb3MgPSBUUlVFKQoKdG9wNSA8LSBDbHVzdGVyTWFya2VycyAlPiUgZ3JvdXBfYnkoY2x1c3RlcikgJT4lIHRvcF9uKG49NSwgd3QgPSBhdmdfbG9nMkZDKQpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gdG9wNSRnZW5lLCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuNicpCgp3cml0ZS5jc3YoQ2x1c3Rlck1hcmtlcnMsIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL1BoZW5vSUQvc2NSTkFzZXFTb3J0ZWQvTmV1cm9uczFDbHVzdGVyTWFya2VyczExLmNzdiIpCgpgYGAKQ2x1c3RlciAwIGhhcyBmZXdlciBtYXJrZXJzLiAKMiBhbmQgNSBoYXZlIHNpbWlsYXIgdXAgcmVnIG1hcmtlcnMKMyBhbmQgNCBhbHNvIG92ZXJsYXAKCgoKTG9vayBhdCB0aGUgY2x1c3RlciBtYXJrZXJzIGluIGNlbGwgdHlwZSBsaWJyYXJpZXMgZm9yIE5ldXJvbnMgMgoKYGBge3J9CmxpYnJhcnkoZW5yaWNoUikKZGIgPC0gYygnQWxsZW5fQnJhaW5fQXRsYXNfdXAnLCdEZXNjYXJ0ZXNfQ2VsbF9UeXBlc19hbmRfVGlzc3VlXzIwMjEnLAogICAgICAgICdDZWxsTWFya2VyX0F1Z21lbnRlZF8yMDIxJywnQXppbXV0aF9DZWxsX1R5cGVzXzIwMjEnKQoKIyBlbnJpY2hyKGdlbmVzLCBkYXRhYmFzZXMgPSBOVUxMKQojIGNsdXN0ZXIgMAoKTjEuYzAgPC0gQ2x1c3Rlck1hcmtlcnMgJT4lIGZpbHRlcihjbHVzdGVyID09IDAgJiBhdmdfbG9nMkZDID4gMCkKZ2VuZXMgPC0gTjEuYzAkZ2VuZQoKTjEuYzAuRXIgPC0gZW5yaWNocihnZW5lcywgZGF0YWJhc2VzID0gZGIpCnBsb3RFbnJpY2goTjEuYzAuRXJbWzFdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzAuRXJbWzJdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzAuRXJbWzNdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCgpOMS5Fci5nZW5lcy4xIDwtIE4xLmMwLkVyW1sxXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjEKCk4xLkVyLmdlbmVzLjIgPC0gTjEuYzAuRXJbWzJdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMgoKTjEuRXIuZ2VuZXMuMyA8LSBOMS5jMC5FcltbM11dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4zCgojIGNsdXN0ZXIgMQoKTjEuYzEgPC0gQ2x1c3Rlck1hcmtlcnMgJT4lIGZpbHRlcihjbHVzdGVyID09IDEgJiBhdmdfbG9nMkZDID4gMCkKZ2VuZXMgPC0gTjEuYzEkZ2VuZQoKTjEuYzEuRXIgPC0gZW5yaWNocihnZW5lcywgZGF0YWJhc2VzID0gZGIpCnBsb3RFbnJpY2goTjEuYzEuRXJbWzFdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzEuRXJbWzJdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzEuRXJbWzNdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzEuRXJbWzRdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCgpOMS5Fci5nZW5lcy4xIDwtIE4xLmMxLkVyW1sxXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjEKCk4xLkVyLmdlbmVzLjIgPC0gTjEuYzEuRXJbWzJdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMgoKTjEuRXIuZ2VuZXMuMyA8LSBOMS5jMS5FcltbM11dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4zCgpOMS5Fci5nZW5lcy40IDwtIE4xLmMxLkVyW1s0XV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjQKCiMgY2x1c3RlciAxOyBvbGZhY3RvcnkgYnVsYiwgbmV1cmFsIHBsYXRlLCBtYXliZSBSYWRpYWwgR2xpYSwgCk4xLmMyIDwtIENsdXN0ZXJNYXJrZXJzICU+JSBmaWx0ZXIoY2x1c3RlciA9PSAyICYgYXZnX2xvZzJGQyA+IDApCmdlbmVzIDwtIE4xLmMyJGdlbmUKCk4xLmMyLkVyIDwtIGVucmljaHIoZ2VuZXMsIGRhdGFiYXNlcyA9IGRiKQpwbG90RW5yaWNoKE4xLmMyLkVyW1sxXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmMyLkVyW1syXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmMyLkVyW1szXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmMyLkVyW1s0XV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQoKTjEuRXIuZ2VuZXMuMSA8LSBOMS5jMi5FcltbMV1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4xCgpOMS5Fci5nZW5lcy4yIDwtIE4xLmMyLkVyW1syXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjIKCk4xLkVyLmdlbmVzLjMgPC0gTjEuYzIuRXJbWzNdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMwoKTjEuRXIuZ2VuZXMuNCA8LSBOMS5jMi5FcltbNF1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy40CgojIGNsdXN0ZXIgMwoKTjEuYzMgPC0gQ2x1c3Rlck1hcmtlcnMgJT4lIGZpbHRlcihjbHVzdGVyID09IDMgJiBhdmdfbG9nMkZDID4gMCkKZ2VuZXMgPC0gTjEuYzMkZ2VuZQoKTjEuYzMuRXIgPC0gZW5yaWNocihnZW5lcywgZGF0YWJhc2VzID0gZGIpCnBsb3RFbnJpY2goTjEuYzMuRXJbWzFdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzMuRXJbWzJdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzMuRXJbWzNdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzMuRXJbWzRdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCgpOMS5Fci5nZW5lcy4xIDwtIE4xLmMzLkVyW1sxXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjEKCk4xLkVyLmdlbmVzLjIgPC0gTjEuYzMuRXJbWzJdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMgoKTjEuRXIuZ2VuZXMuMyA8LSBOMS5jMy5FcltbM11dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4zCgpOMS5Fci5nZW5lcy40IDwtIE4xLmMzLkVyW1s0XV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjQKCiMgY2x1c3RlciA0CgpOMS5jNCA8LSBDbHVzdGVyTWFya2VycyAlPiUgZmlsdGVyKGNsdXN0ZXIgPT0gNCAmIGF2Z19sb2cyRkMgPiAwKQpnZW5lcyA8LSBOMS5jNCRnZW5lCgpOMS5jNC5FciA8LSBlbnJpY2hyKGdlbmVzLCBkYXRhYmFzZXMgPSBkYikKcGxvdEVucmljaChOMS5jNC5FcltbMV1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jNC5FcltbMl1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jNC5FcltbM11dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jNC5FcltbNF1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKCk4xLkVyLmdlbmVzLjEgPC0gTjEuYzQuRXJbWzFdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMQoKTjEuRXIuZ2VuZXMuMiA8LSBOMS5jNC5FcltbMl1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4yCgpOMS5Fci5nZW5lcy4zIDwtIE4xLmM0LkVyW1szXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjMKCk4xLkVyLmdlbmVzLjQgPC0gTjEuYzQuRXJbWzRdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuNAoKIyBjbHVzdGVyIDUKCk4xLmM1IDwtIENsdXN0ZXJNYXJrZXJzICU+JSBmaWx0ZXIoY2x1c3RlciA9PSA1ICYgYXZnX2xvZzJGQyA+IDApCmdlbmVzIDwtIE4xLmM1JGdlbmUKCk4xLmM1LkVyIDwtIGVucmljaHIoZ2VuZXMsIGRhdGFiYXNlcyA9IGRiKQpwbG90RW5yaWNoKE4xLmM1LkVyW1sxXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmM1LkVyW1syXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmM1LkVyW1szXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmM1LkVyW1s0XV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQoKTjEuRXIuZ2VuZXMuMSA8LSBOMS5jNS5FcltbMV1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4xCgpOMS5Fci5nZW5lcy4yIDwtIE4xLmM1LkVyW1syXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjIKCk4xLkVyLmdlbmVzLjMgPC0gTjEuYzUuRXJbWzNdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMwoKTjEuRXIuZ2VuZXMuNCA8LSBOMS5jNS5FcltbNF1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy40CgojIGNsdXN0ZXIgNgoKTjEuYzYgPC0gQ2x1c3Rlck1hcmtlcnMgJT4lIGZpbHRlcihjbHVzdGVyID09IDYgJiBhdmdfbG9nMkZDID4gMCkKZ2VuZXMgPC0gTjEuYzYkZ2VuZQoKTjEuYzYuRXIgPC0gZW5yaWNocihnZW5lcywgZGF0YWJhc2VzID0gZGIpCnBsb3RFbnJpY2goTjEuYzYuRXJbWzFdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzYuRXJbWzJdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzYuRXJbWzNdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzYuRXJbWzRdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCgpOMS5Fci5nZW5lcy4xIDwtIE4xLmM2LkVyW1sxXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjEKCk4xLkVyLmdlbmVzLjIgPC0gTjEuYzYuRXJbWzJdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMgoKTjEuRXIuZ2VuZXMuMyA8LSBOMS5jNi5FcltbM11dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4zCgpOMS5Fci5nZW5lcy40IDwtIE4xLmM2LkVyW1s0XV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjQKCgojIG90aGVyIGNsdXN0ZXJzIC0gY2hhbmdlIHRoZSBjbHVzdGVyIG51bWJlcgpOMS5jNiA8LSBDbHVzdGVyTWFya2VycyAlPiUgZmlsdGVyKGNsdXN0ZXIgPT0gMTEgJiBhdmdfbG9nMkZDID4gMCkKZ2VuZXMgPC0gTjEuYzYkZ2VuZQoKTjEuYzYuRXIgPC0gZW5yaWNocihnZW5lcywgZGF0YWJhc2VzID0gZGIpCnBsb3RFbnJpY2goTjEuYzYuRXJbWzFdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzYuRXJbWzJdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzYuRXJbWzNdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzYuRXJbWzRdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCgpOMS5Fci5nZW5lcy4xIDwtIE4xLmM2LkVyW1sxXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjEKCk4xLkVyLmdlbmVzLjIgPC0gTjEuYzYuRXJbWzJdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMgoKTjEuRXIuZ2VuZXMuMyA8LSBOMS5jNi5FcltbM11dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4zCgpOMS5Fci5nZW5lcy40IDwtIE4xLmM2LkVyW1s0XV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjQKCgpgYGAKCmNsdXN0ZXIgMCAtIGFzdHJvY3l0ZSwgcmFkaWFsIGdsaWEsIG1pY3JvZ2xpYSwgc3RyaWF0dW0gLSB2ZXJ5IGZldyBnZW5lcyBpbiB0aGVzZSB0ZXJtcwpjbHVzdGVyIDEgLSBhZHJlbmFsLCB0aGFsbXVzLCBlbmRvdGhlbGlhbCwgYXN0cm9jeXRlcywgbmV1cm9ucwpjbHVzdGVycyAyIC0gbmV1cmFsIHBsYXRlLCBzdHJhdHVtLCBuZXVyb25zLCBOUEMsIHN0ZW0sIGFzdHJvLG5ldXJvZW5kb2NyaW5lCmNsdXN0ZXIgMyAtIGJyYWluIG1vbGVjdWxhciBsYXllciwgZW5kb3RoZWxpYWwsIGFzdHJvY3l0ZSBlbWJyeW9uaWMsIApjbHVzdGVyIDQgLSBERywgc3RyaWF0dW0gQ0EzLCBHQUJBZXJnaWMgbmV1cm9ucwpjbHVzdGVyIDUgLSBERywgbmV1cm9ucywgR2x1dGFtYXRlcmdpYyBuZXVyb25zCmNsdXN0ZXIgNiAtIG5ldXJvbnMsIGFzdHJvY3l0ZSwgbWljcm9nbGlhLCBHQUJBbmV1cm9ucwpjbHVzdGVyIDcgLSBuZXVyb25zLCBnbHV0IGFuZCBnYWJhCmNsdXN0ZXIgOCAtIGFzdHJvY3l0ZSwgZW5kb3RoZWxpYWwsIHBlcmljeXRlCmNsdXN0ZXIgOSAtIGVwaXRoZWxpYWwsIGVtYnJ5b25pYyBhc3Ryb2N5dGVzLCBHQUJBIG5ldXJvbnMKY2x1c3RlciAxMCAtIGVwaXRoZWxpYWwKY2x1c3RlciAxMSAtIGVuZG90aGVsaWFsLCBpbW11bmUgY2VsbHMgVCBjZWxscwoKCkV4cHJlc3Npb24gb2YgbWFya2VycyBnZW5lcyBpbiBOZXVyb25zMiAKCmBgYHtyfQoKZmVhdHVyZV9saXN0ID0gYygiTUtJNjciLCJTT1gyIiwiUE9VNUYxIiwiRExYMiIsIlBBWDYiLCJTT1g5IiwiSEVTMSIsIk5FUyIsIlJCRk9YMyIsIk1BUDIiLCJOQ0FNMSIsIkNEMjQiLCJHUklBMiIsIkdSSU4yQiIsIkdBQkJSMSIsIkdBRDEiLCJHQUQyIiwiR0FCUkExIiwiR0FCUkIyIiwiVEgiLCJBTERIMUExIiwiTE1YMUIiLCJOUjRBMiIsIkNPUklOIiwiQ0FMQjEiLCJLQ05KNiIsIkNYQ1I0IiwiSVRHQTYiLCJTTEMxQTMiLCJDRDQ0IiwiQVFQNCIsIlMxMDBCIiwgIlBER0ZSQSIsIk9MSUcyIiwiTUJQIiwiQ0xETjExIiwiVklNIiwiVkNBTTEiKQoKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IGZlYXR1cmVfbGlzdCwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjYnKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IGZlYXR1cmVfbGlzdCkgK1JvdGF0ZWRBeGlzKCkKClBEX3BvdWxpbiA9IGMoIlRIIiwiU0xDNkEzIiwiU0xDMThBMiIsIlNPWDYiLCJORE5GIiwiU05DRyIsIkFMREgxQTEiLCJDQUxCMSIsIlRBQ1IyIiwiU0xDMTdBNiIsIlNMQzMyQTEiLCJPVFgyIiwiR1JQIiwiTFBMIiwiQ0NLIiwiVklQIikKCkRvSGVhdG1hcChzZXUucSwgZmVhdHVyZXMgPSBQRF9wb3VsaW4sIHNpemU9MywgYW5nbGUgPTkwLCBncm91cC5iYXIuaGVpZ2h0ID0gMC4wMiwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC42JykKRG90UGxvdChzZXUucSwgZmVhdHVyZXMgPSBQRF9wb3VsaW4pK1JvdGF0ZWRBeGlzKCkKCmVhbHJ5TmV1ciA9IGMoIkRDWCIsIk5FVVJPRDEiLCJUQlIxIikKcHJvbGlmZXJhdGlvbiA9IGMoIlBDTkEiLCJNS0k2NyIpCm5ldXJhbHN0ZW0gPSBjKCJTT1gyIiwiTkVTIiwiUEFYNiIsIk1BU0gxIikKCmZlYXR1cmVfbGlzdCA8LSBjKCJEQ1giLCJORVVST0QxIiwiVEJSMSIsIlBDTkEiLCJNS0k2NyIsIlNPWDIiLCJORVMiLCJQQVg2IiwiTUFTSDEiKQpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gZmVhdHVyZV9saXN0LCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuNicpCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gZmVhdHVyZV9saXN0KStSb3RhdGVkQXhpcygpCiMgbm8gcHJvbGlmZXJhdGlvbiBtYXJrZXIgZXhwcmVzc2lvbiAgUENOQSBvciBNS0k2NwojIGNsdXN0ZXIgNCBEQSBuZXVyb25zIC0gc2hvd3MgZWFybHkgbmV1cm9uIG1hcmtlciBhbmQgbG93IFBBWCA0CiMgY2x1c3RlciAzIGhhcyBoaWdoZXIgU09YMiAtIG5ldXJvYmxhc3QgbWFya2VyIC8gTlBDIG1hcmtlcgoKbWF0X25ldXJvbiA9IGMoIlJCRk9YMyIsIlNZUCIsIkRMRzQ1IiwiVkFNUDEiLCJWQU1QMiIsIlRVQkIzIiwiU1lUMSIsIkJTTiIsIkhPTUVSMSIsIlNMQzE3QTYiKSAKIyBOZXVOIGlzIEZPWDMgLSBSQkZPWDMKIyBQU0Q5NSBhbHNvIFNQLTkwIG9yIERMRzQKIyBWR0xVVDIgaXMgU0xDMTdBNgpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gbWF0X25ldXJvbiwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjYnKQojIGNsdXN0ZXIgNCBhbHNvIHNob3cgbWF0dXJlIG5ldXJvbiBtYXJrZXJzCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gbWF0X25ldXJvbikrUm90YXRlZEF4aXMoKQojIGV4Y2l0YXRvcnkgbmV1cm9uIG1hcmtlcnMKZXggPSBjKCJHUklBMiIsIkdSSUExIiwiR1JJQTQiLCJHUklOMSIsIkdSSU4yQiIsIkdSSU4yQSIsIkdSSU4zQSIsIkdSSU4zIiwiR1JJUDEiLCJDQU1LMkEiKQpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gZXgsIHNpemU9MywgYW5nbGUgPTkwLCBncm91cC5iYXIuaGVpZ2h0ID0gMC4wMiwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC42JykKRG90UGxvdChzZXUucSwgZmVhdHVyZXMgPSBleCkrUm90YXRlZEF4aXMoKQojIGluaGliaXRvcnkgbmV1cm9uIG1hcmtlcnMKaW5oID0gYygiR0FEMSIsIkdBRDIiLCAiR0FUMSIsIlBWQUxCIiwiR0FCUjIiLCJHQUJSMSIsIkdCUlIxIiwiR0FCUkIyIiwiR0FCUkIxIiwiR0FCUkIzIiwiR0FCUkE2IiwiR0FCUkExIiwiR0FCUkE0IiwiVFJBSzIiKQpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gaW5oLCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuNicpCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gaW5oKStSb3RhdGVkQXhpcygpCiMgY2x1c3RlciA0IGlzIG1vcmUgZXhjaXRhdG9yeSB0aGFuIGluaGJpdG9yeSBidXQgbmVpdGhlciBtYXJrZXIgc2V0IGhhcyBtdWNoIGV4cHJlc3Npb24gCgojIyMgZ2xpYSBtYXJrZXJzCm1pY3JvZ2xpYSA9IGMoIlBUUFJDIiwiQUlGMSIsIkFER1JFMSIpICAjIEFER1JFMSBpcyBhIG1pY3JvZ2xpYSBtYXJrZXIgRjQvODAsIENENDUgaXMgUFRQUkMsIGdlbmUgbmFtZSBJQkExIGlzIEFJRjEKYXN0b2xnTlBDcHJvbWljcm8gPSBjKCJHRkFQIiwiUzEwMEIiLCJTTEMxQTIiLCJNQlAiLCJTT1gxMCIsIlNQUDEiLCJEQ1giLCJORVVST0QxIiwiVEJSMSIsIlBDTkEiLCJNS0k2NyIsIlBUUFJDIiwiQUlGMSIsIkFER1JFMSIpCiMgbm90ZSBHTFQxIGlzIEVBQVQyIHdoaWNoIGlzIFNMQzFBMiBnbHV0YXRtYXRlIHRyYW5zcG9ydGVyCiMgZXBpdGhlbGlhbAplcGkgPSBjKCJIRVMxIiwiSEVTNSIsIlNPWDIiLCJTT1gxMCIsIk5FUyIsIkNESDEiLCJOT1RDSDEiKSAjIGUtY2FkaGVyaW4gaXMgQ0RIMQoKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IGFzdG9sZ05QQ3Byb21pY3JvLCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuNicpCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gYXN0b2xnTlBDcHJvbWljcm8sIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuNicpK1JvdGF0ZWRBeGlzKCkKIyBjbHVzdGVyIDQgaXMgbW9yZSBleGNpdGF0b3J5IHRoYW4gaW5oYml0b3J5IGJ1dCBuZWl0aGVyIG1hcmtlciBzZXQgaGFzIG11Y2ggZXhwcmVzc2lvbiAKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IGVwaSwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjYnKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IGVwaSwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC42JykrUm90YXRlZEF4aXMoKQoKIyBhbHNvIGFkZCBSYWRpYWwgZ2xpYSBtYXJrZXIgb3ZlcmxhcCB3aXRoIEdsaWEgYW5kIE5ldXJvbnMKCmZlYXR1cmVzIDwtIGMoIlBUUFJDIiwiQUlGMSIsIkFER1JFMSIsICJWSU0iLCAiVE5DIiwiUFRQUloxIiwiRkFNMTA3QSIsIkhPUFgiLCJMSUZSIiwKICAgICAgICAgICAgICAiSVRHQjUiLCJJTDZTVCIpCkRvSGVhdG1hcChzZXUucSwgZmVhdHVyZXMgPSBmZWF0dXJlcywgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjYnKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IGZlYXR1cmVzLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjYnKStSb3RhdGVkQXhpcygpCgoKYGBgCgoKTGFiZWwgdGhlIE5ldXJvbjIgRkFDUyBwb3B1bGF0aW9uIAoKYGBge3J9CgpJZGVudHMoc2V1LnEpIDwtICdSTkFfc25uX3Jlcy4wLjYnCmNsdXN0ZXIuaWRzIDwtIGMoIk5ldXJvbnMxIiwiaW1tYXR1cmVOZXVyb25zMSIsIk5ldXJvbnMyIiwKICAgICAgICAgICAgICAgICAiT3RoZXIiLCJEQW5ldXJvbnMxIiwiREFuZXVyb25zMiIsImltbWF0dXJlTmV1cm9uczIiLAogICAgICAgICAgICAgICAgICJEQW5ldXJvbnMzIiwiUkciLCJpbW1hdHVyZU5ldXJvbnMxIiwiRXBpdGhlbGlhbCIsIkVuZG90aGVsaWFsIikKdW5pcXVlKHNldS5xJFJOQV9zbm5fcmVzLjAuNikKCm5hbWVzKGNsdXN0ZXIuaWRzKSA8LSBsZXZlbHMoc2V1LnEpCnNldS5xIDwtIFJlbmFtZUlkZW50cyhzZXUucSwgY2x1c3Rlci5pZHMpCnNldS5xJHN1Ymdyb3VwcyA8LSBJZGVudHMoc2V1LnEpCgpEaW1QbG90KHNldS5xLCByZWR1Y3Rpb24gPSAidW1hcCIsIGxhYmVsID0gVFJVRSwgZ3JvdXAuYnkgPSAnc3ViZ3JvdXBzJywgcmVwZWwgPSBUUlVFKQoKCiMgbGFiZWwgYWdhaW4gd2l0aCBqdXN0IG51bWJlcmluZwojIHRoZW4gSSdsbCBmaW5kIG1hcmtlcnMgaW4gcGFpcnMgdG8gZGlzdGluZ3Vpc2ggZ3JvdXBzLiAKCklkZW50cyhzZXUucSkgPC0gJ1JOQV9zbm5fcmVzLjAuNicKY2x1c3Rlci5pZHMgPC0gYygiTmV1cm9uczEiLCJOZXVyb25zMiIsIk5ldXJvbnMzIiwKICAgICAgICAgICAgICAgICAiT3RoZXIiLCJEQW5ldXJvbnMxIiwiREFuZXVyb25zMiIsIk5ldXJvbnM0IiwKICAgICAgICAgICAgICAgICAiREFuZXVyb25zMyIsIlJHIiwiTmV1cm9uczIiLCJFcGl0aGVsaWFsIiwiRW5kb3RoZWxpYWwiKQp1bmlxdWUoc2V1LnEkUk5BX3Nubl9yZXMuMC42KQoKbmFtZXMoY2x1c3Rlci5pZHMpIDwtIGxldmVscyhzZXUucSkKc2V1LnEgPC0gUmVuYW1lSWRlbnRzKHNldS5xLCBjbHVzdGVyLmlkcykKc2V1LnEkbnVtYmVyLmdyb3VwcyA8LSBJZGVudHMoc2V1LnEpCgpEaW1QbG90KHNldS5xLCByZWR1Y3Rpb24gPSAidW1hcCIsIGxhYmVsID0gVFJVRSwgZ3JvdXAuYnkgPSAnbnVtYmVyLmdyb3VwcycsIHJlcGVsID0gVFJVRSkKCgpzYXZlUkRTKHNldS5xLCAiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvUGhlbm9JRC9zY1JOQXNlcVNvcnRlZC9vYmpzL05ldXJvbnMyTGFiZWxzU2V1MzAwOTIwMjIuUkRTIikKCgoKYGBgCgpQcm9wb3J0aW9ucyBvZiBjZWxsIHR5cGVzCgpgYGB7cn0KCgoKYGBgCgoKCgoKCkZpbmQgbWFya2VycyBpbiBwYWlycyB0byBnbyBiYWNrIGFuZCBjbGFzc2lmeSB0aGUgc3ViZ3JvdXBzLgpXaWxsIG5lZWQgdG8gcmV0dXJuIHRvIHRoaXMgZm9yIE5ldXJvbnMxIEZBQ1MKCk5ldXJvbnMgNSBhbmQgTmV1cm9uczIgaGFkIHNpbWlsYXIgbWFya2VycyBhbmQgd2VyZSBtZXJnZWQKU3Vic2V0IGFnYWluCgpgYGB7cn0KCiMgZmFzdGVyIHRvIG1ha2UgYSBzdWJzZXQgb2JqZWN0cyBvZiBvbmx5IG5ldXJvbnMgYW5kIHVzZSBmaW5kIGFsbCBtYXJrZXJzCgpuZXVyb24uc3ViIDwtIHN1YnNldChzZXUucSwgaWRlbnRzID0gYygiTmV1cm9uczEiLCJOZXVyb25zMiIsIk5ldXJvbnMzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5ldXJvbnM0IikpCgpuZXVyb24uc3ViLm1hcmtlcnMgPC0gRmluZEFsbE1hcmtlcnMobmV1cm9uLnN1YikKCnRvcDUgPC0gbmV1cm9uLnN1Yi5tYXJrZXJzICU+JSBncm91cF9ieShjbHVzdGVyKSAlPiUgdG9wX24obj01LCB3dCA9IGF2Z19sb2cyRkMpCkRvSGVhdG1hcChuZXVyb24uc3ViLCBmZWF0dXJlcyA9IHRvcDUkZ2VuZSwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQoKRG90UGxvdChuZXVyb24uc3ViLCBmZWF0dXJlcyA9IHRvcDUkZ2VuZSkgKyBSb3RhdGVkQXhpcygpCgoKIyBuZXVyb25zIDUgd2FzIGpvaW5lZCB0byBOZXVyb25zIDIKIyBjbHVzdGVyIG1hcmtlcnMgZG9uZSBhZ2FpbgoKIyBOZXVyb25zMSA6IE1HUCAodGFyZ2V0aW5nIG5ldXJhbCBwcm9qZWN0aW9ucyBCTVAgc2lnbmFsaW5nKSwgSFBEIChleGNpdGF0b3J5IGFuZCBpbmliaXRvcnksIGNvdWxkIGJlIGNlbGwgYWRoZXNpb24gb3IgYXBvcHRvc2lzKSwgTVNYMSAodHJhbnNjcmlwdGlvbiBmYWN0b3IgQk1QIHNpZ25hbGluZywgbWlkYnJhaW4gbWFya2VyLCBkZXZlbG9wbWVudGFsKSwgQ1lQMUIxIChyZWRveCBob21lb3N0YXRpcykgICAKIyBNR1AsIEhQRCwgTVNYMSwgQ1lQMUIxCgojIHRoZXJlIGlzbid0IGEgZ29vZCBwcm9wb3J0aW9uIG9mIGNlbGxzIGV4cHJlc3Npb24gYW55IG9mIHRoZSBtYXJrZXJzLCBOZXVyb25zMiBoYXMgdGhlIGJlc3QgYW1vdW50CgojIE5ldXJvbnMyOiBURlAxMiBzZXJpbmUgcHJvdGVhc2UgbWVsYXRvbmluIGNvbnZlcnNpb24sIFBUTiAoY3l0b2tpbmUgc2lnbmFsaW5nKSwgTFlnSCAoaW5oYW5jZXMgbkFDaFJzKSwgUzEwMEExMCAobW9kdWxhdGVzIHNlcm90b25pbiByZWNlcHRvciksIElGSTI3IChhbnRpdmlyYWwgYWN0aXZpdHkpCiNURlAxMixQVE4sIExZNkgsIFMxMDBBMTAsIElGSTI3IAoKIyBOZXVyb25zMzogU09YNCwgQVNDTDEgKG5ldXJvZ2VuZXNpcyksCgojIFNPWDQgaXMgYSBtYXJrZXIgb2YgMyBidXQgaGFzIGhpZ2ggZXhwcmVzc2lvbiBpbiA0IGFzIHdlbGwgCgojIE5ldXJvbnM0OiBQQ0FUNCAobm90IG5vdGVkIGluIG5ldXJvbnMpLCBUUEgxICg1SFQgc3ludGhlc2lzKSwgR0s1IChuZXVyb25hbCBtYWludGFpbmFuY2UpLCBTU1QgKHNvbWF0b3N0YXRpbiwgR0FCQSBzcGlrZSByZWd1bGF0aW9uKSwgVFRSIChuZXVyYWwgcHJvdGVjdGl2ZSBpbiBBRCkKIyBQQ0FUNCwgVFBIMSwgR0s1LCBTU1QsIFRUUgoKIyBtYXJrZXJzIHRvIHVzZQoKIyBOZXVyb25zMTogTVNYMSwgQ1lQMUIxICAgICAgCiMgTmV1cm9uczI6IExZNkgsIFMxMDBBMTAgICAgIAojIE5ldXJvbnMzOiBTT1g0LCBBU0NMMSAoTmV1cm9nZW5lc2lzKSBJbW1hdHVyZQojIE5ldXJvbnM0OiBHSzUsIFNTVCAgICAgICAgICAgICAgICAgICAgICAgICBNb3JlIG1hdHVyZQoKCgojIE1heWJlIG5ldXJvbnMgMSBhbmQgMiBjb3VsZCBiZSBtZXJnZWQKCiMgbGV0cyBzZWUgaG93IHRoZSBtYXJrZXJzIHdvdWxkIGxvb2sKCm5ldXJvbnMuMWFuZDIgPC0gRmluZE1hcmtlcnMobmV1cm9uLnN1YiwgaWRlbnQuMSA9IGMoIk5ldXJvbnMxIiwiTmV1cm9uczIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZGVudC4yID0gYygiTmV1cm9uczMiLCJOZXVyb25zNCIpKQoKdG9wMTAgPC0gbmV1cm9ucy4xYW5kMiAlPiUgdG9wX24obj0xMCwgd3QgPSBhdmdfbG9nMkZDKQpmdC51cCA8LSByb3duYW1lcyh0b3AxMCkgIyB1cCBpbiBOZXVyb25zMSBhbmQgMwp0b3AxMCA8LSBuZXVyb25zLjFhbmQyICU+JSB0b3BfbihuPS0xMCwgd3QgPSBhdmdfbG9nMkZDKQpmdC5kb3duIDwtIHJvd25hbWVzKHRvcDEwKQpmZWF0dXJlcyA8LSBjKGZ0LnVwLGZ0LmRvd24pCgpEb0hlYXRtYXAobmV1cm9uLnN1YiwgZmVhdHVyZXMgPSBmZWF0dXJlcywgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQoKRG90UGxvdChuZXVyb24uc3ViLCBmZWF0dXJlcyA9IGZlYXR1cmVzKSArIFJvdGF0ZWRBeGlzKCkKCiMgYWxsIHRoZSBtYXJrZXJzIHdlcmUgdXAgcmVndWxhdGVkIGluIG5ldXJvbnMyIGFuZCBub3QgcmVhbGx5IG5ldXJvbnMxCiMgSSdsbCBrZWVwIHRoZW0gc2VwYXJhdGVkCgoKYGBgCgoKVXNlIHN1Ymdyb3VwaW5nIGFuZCBmaW5kIGNsdXN0ZXIgbWFya2VycyB0byBsb29rIGF0IG5ldXJvbmFsIHN1YnR5cGVzLgoKYGBge3J9CgojIGZhc3RlciB0byBtYWtlIGEgc3Vic2V0IG9iamVjdHMgb2Ygb25seSBuZXVyb25zIGFuZCB1c2UgZmluZCBhbGwgbWFya2VycwoKbmV1cm9uLnN1YiA8LSBzdWJzZXQoc2V1LnEsIGlkZW50cyA9IGMoIkRBbmV1cm9uczEiLCJEQW5ldXJvbnMyIiwiREFuZXVyb25zMyIpKQoKbmV1cm9uLnN1Yi5tYXJrZXJzIDwtIEZpbmRBbGxNYXJrZXJzKG5ldXJvbi5zdWIpCgp0b3A1IDwtIG5ldXJvbi5zdWIubWFya2VycyAlPiUgZ3JvdXBfYnkoY2x1c3RlcikgJT4lIHRvcF9uKG49NSwgd3QgPSBhdmdfbG9nMkZDKQpEb0hlYXRtYXAobmV1cm9uLnN1YiwgZmVhdHVyZXMgPSB0b3A1JGdlbmUsIHNpemU9MywgYW5nbGUgPTkwLCBncm91cC5iYXIuaGVpZ2h0ID0gMC4wMikKCkRvdFBsb3QobmV1cm9uLnN1YiwgZmVhdHVyZXMgPSB0b3A1JGdlbmUpICsgUm90YXRlZEF4aXMoKQoKIyBtYXJrZXJzIGFyZSBtdWNoIGNsZWFyZXIgZm9yIHRoZSBEQSBuZXVyb24gc3ViZ3JvdXBzCgojIERBIG5ldXJvbnMgMTogV0lGMSwgQ1lQMUIxLCBJR0ZCUDMsIEhQRCwgV0ZJS0tOMgojIFdJRjEgKHNlY3JldGVkIFdOVCBpbmhpYml0b3IsIHByb21vdGVzIHJlZ2VuZXJhdGlvbiksIENZUDFCMSAocmVkb3ggaG9tZW9zdGF0aXMpLCBJR0ZCUDMgKHByb2xhY3RpbiBzZWNyZXRpb24gcmVndWxhdGlvbiBoeXBvdGhhbG11cyksIEhQRCAobmV1cm8gcHJvdGVjdGl2ZSksIFdGSUtLTjIgKFJlY2VwdG9yIGZvciBUTkMpCiMgREEgbmV1cm9uczI6IENESDcsIFJVTlgxVDEsIEFTQ0wxLCBETEsxLCBNRUczCiMgQ0RINyAobmV1cm8gY2lyY3VpdHJ5IGRldmVsb3BtZW50LCBTRU1BKSwgUlVOWDFUMSAobmV1cm9uYWwgZGlmZmVyZW50aWF0aW9uKSwgQVNDTDEgKG5ldXJvbmFsIGRpZmZlcmVudGlhdGlvbiksIERMSzEgKG5ldXJhbCBkaWZmZXJlbnRhdGlvbiksIE1FRzMgKG5ldXJhbCBob21lb3N0YXRpcykgIAojIERBIG5ldXJvbnMzOiBQQ0FUNCwgTkVVUk9EMSwgTkNLQVA1LCBHSzUsIFNTVAojIFBDQVQ0IChkZW5kcml0aWMgZ3Jvd3RoKSwgTkVVUk9EMSAobmV1cmFsIGRpZmZlcmVudGF0aW9uKSwgTkNLQVA1IChFeGNpdG9yeSBuZXVyb25zKSwgR0s1IChUSCApLCBTU1QgKHJlZ3VhbGF0ZXMgc3Bpa2UgdGltZXMpCgojIERBIG5ldXJvbnMxOiBDWVAxQjEsIElHRkJQMwojIERBIG5ldXJvbnMyOiBSVU5YMVQxLCBBU0NMMQojIERBIG5ldXJvbnMzOiBORVVST0QxLCBOQ0tBUDUKCgpgYGAKCgpOYW1lIHRoZSBOZXVyb25zMiBGQUNTIHBvcHVsYXRpb24gd2l0aCB0aGUgTmV1cm9uIHN1YnR5cGUgbGF0dGVyLgoKYGBge3J9CgpJZGVudHMoc2V1LnEpIDwtICdSTkFfc25uX3Jlcy4wLjYnCmNsdXN0ZXIuaWRzIDwtIGMoIk5ldXJvbnMtTVNYMSIsIk5ldXJvbnMtTFk2SCIsIk5ldXJvbnMtQVNDTDEiLAogICAgICAgICAgICAgICAgICJPdGhlciIsIkRBbmV1cm9ucy1DWVAxQjEiLCJEQW5ldXJvbnMtQVNDTDEiLCJOZXVyb25zLUdLNSIsCiAgICAgICAgICAgICAgICAgIkRBbmV1cm9ucy1ORVVST0QxIiwiUkciLCJOZXVyb25zLUxZNkgiLCJFcGl0aGVsaWFsIiwiRW5kb3RoZWxpYWwiKQoKdW5pcXVlKHNldS5xJFJOQV9zbm5fcmVzLjAuNikKCm5hbWVzKGNsdXN0ZXIuaWRzKSA8LSBsZXZlbHMoc2V1LnEpCnNldS5xIDwtIFJlbmFtZUlkZW50cyhzZXUucSwgY2x1c3Rlci5pZHMpCnNldS5xJGNlbGxzdWJncm91cHMgPC0gSWRlbnRzKHNldS5xKQoKRGltUGxvdChzZXUucSwgcmVkdWN0aW9uID0gInVtYXAiLCBsYWJlbCA9IFRSVUUsIGdyb3VwLmJ5ID0gJ2NlbGxzdWJncm91cHMnLCByZXBlbCA9IFRSVUUpCgoKYGBgCgpgYGB7cn0KCiMgc2F2ZSB0aGUgTmV1cm9uczIgd2l0aCBsYWJlbHMKCnNhdmVSRFMoc2V1LnEsICIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9QaGVub0lEL3NjUk5Bc2VxU29ydGVkL29ianMvTmV1cm9uczJMYWJlbHNTZXUzMDA5MjAyMi5SRFMiKQoKYGBgCgoKRkFDUyBwb3B1bGF0aW9uIEdsaWExIChzaG91bGQgYmUgYXN0cm9jeXRlcykKCmBgYHtyfQojIGV4cGxvcmUgZmlsdGVyaW5nCnNldSA8LSBHbGlhMQpzZXUKIyAKVmxuUGxvdChzZXUsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIsICJuQ291bnRfUk5BIiwgInBlcmNlbnQubXQiKSwgbmNvbCA9IDMpCgpWbG5QbG90KHNldSwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiksIHkubWF4ID0gMTAwMCkKVmxuUGxvdChzZXUsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIpLCB5Lm1heCA9IDUwMCkKVmxuUGxvdChzZXUsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5Db3VudF9STkEiKSwgeS5tYXggPSAyMDAwKQoKIyBmaWx0ZXIgbW9yZSBjZWxscwoKc2V1LmZ0IDwtIHN1YnNldChzZXUsIHN1YnNldCA9IG5GZWF0dXJlX1JOQSA+IDMwMCAmIG5Db3VudF9STkEgPiA1MDAgJiBuQ291bnRfUk5BIDwgMTAwMDApIApzZXUuZnQKCiMgc3RpbGwgYSBsb3Qgb2YgY2VsbHMgNDcyOTUKIyB3aWxsIGxpa2VseSByZW1vdmUgYSBsb3QgbW9yZSB3aXRoIHRoZSBkb3VibGV0IGZpbmRlcgoKCmBgYAoKYGBge3J9CgpzYXZlUkRTKHNldS5mdCwgIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL1BoZW5vSUQvc2NSTkFzZXFTb3J0ZWQvb2Jqcy9HbGlhMUFzdHJvU2V1MDExMDIwMjIuUkRTIikKCnNldS5mdCA8LSByZWFkUkRTKCIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9QaGVub0lEL3NjUk5Bc2VxU29ydGVkL29ianMvR2xpYTFBc3Ryb1NldTAxMTAyMDIyLlJEUyIpCgpzZXUuZnQgPC0gcmVhZFJEUygiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvUGhlbm9JRC9zY1JOQXNlcVNvcnRlZC9vYmpzL0dsaWExQXN0cm9TZXUwMTEwMjAyMi5SRFMiKQoKYGBgCgpEb3VibGV0IGZpbmRlcgoKYGBge3J9CgpzdXBwcmVzc01lc3NhZ2VzKHJlcXVpcmUoRG91YmxldEZpbmRlcikpCgojIGZpbHRlcmluZyBvdXQgTUFMQVQxIGFuZCBtaXRvY2hvbmRyaWFsIGdlbmVzCgpzZXUuZnQgPC0gc2V1LmZ0WyFncmVwbCgiTUFMQVQxIiwgcm93bmFtZXMoc2V1LmZ0KSksIF0Kc2V1LmZ0IDwtIHNldS5mdFshZ3JlcGwoIl5NVC0iLCByb3duYW1lcyhzZXUuZnQpKSwgXQoKIyBsaWtlIGluIHRoZSB0dXRvcmlhbCBJJ20gZm9sbG93aW5nIE1BTEFUMSBpcyB0aGUgdG9wIG1vc3QgZXhwcmVzc2VkIGdlbmUuICBUaGUgdG9wIGdlbmVzIGFyZSBhIGxvdCBvZiBNVCBhbmQgUmlib3NvbWFsIGdlbmVzCgpzZXUuZnRbWyJwZXJjZW50LnJiIl1dIDwtIFBlcmNlbnRhZ2VGZWF0dXJlU2V0KHNldS5mdCwgcGF0dGVybiA9ICJeUlAiKQoKIyBkb3duIHNhbXBsZSB0aGVyZSBhcmUgdG9vIG1hbnkgY2VsbHMgdG8gcnVuIGRvdWJsZXQgZmluZGVyCnNldS5zdWIgPC0gc3Vic2V0KHNldS5mdCwgZG93bnNhbXBsZSA9IDIwMDAwKQoKc2V1LmQgPSBOb3JtYWxpemVEYXRhKHNldS5zdWIpCnNldS5kID0gRmluZFZhcmlhYmxlRmVhdHVyZXMoc2V1LmQsIHZlcmJvc2UgPSBGKQpzZXUuZCA9IFNjYWxlRGF0YShzZXUuZCwgdmFycy50by5yZWdyZXNzID0gYygibkZlYXR1cmVfUk5BIiwgInBlcmNlbnQubXQiKSwKICAgIHZlcmJvc2UgPSBGKQpzZXUuZCA9IFJ1blBDQShzZXUuZCwgdmVyYm9zZSA9IEYsIG5wY3MgPSAxNSkKc2V1LmQgPSBSdW5VTUFQKHNldS5kLCBkaW1zID0gMToxMCwgdmVyYm9zZSA9IEYpCgpuRXhwIDwtIHJvdW5kKG5jb2woc2V1LmQpICogMC4xNSkgICMgZXhwZWN0IG1vcmUgZG91YmxldHMgYmVjYXVzZSB0aGVyZSBpcyBhIGxvdCBtb3JlIGNlbGxzCnNldS5kIDwtIGRvdWJsZXRGaW5kZXJfdjMoc2V1LmQsIHBOID0gMC4yNSwgcEsgPSAwLjA5LCBuRXhwID0gbkV4cCwgUENzID0gMToxMCkKIyB0aGUgbWVtb3J5IGxpbWl0IGlzIHJlYWNoZWQgaGVyZSAtIEkgY291bGQgcnVuIG9uIGNvbXB1dGUgY2FuYWRhCiMgRm9yIG5vdyBJJ2xsIGRvd25zYW1wbGUKIyB0aGlzIHdvcmtzCgojIG5hbWUgb2YgdGhlIERGIHByZWRpY3Rpb24gY2FuIGNoYW5nZSwgc28gZXh0cmFjdCB0aGUgY29ycmVjdCBjb2x1bW4gbmFtZS4KREYubmFtZSA9IGNvbG5hbWVzKHNldS5kQG1ldGEuZGF0YSlbZ3JlcGwoIkRGLmNsYXNzaWZpY2F0aW9uIiwgY29sbmFtZXMoc2V1LmRAbWV0YS5kYXRhKSldCgoKY293cGxvdDo6cGxvdF9ncmlkKG5jb2wgPSAyLCBEaW1QbG90KHNldS5kLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikgKyBOb0F4ZXMoKSwKICAgIERpbVBsb3Qoc2V1LmQsIGdyb3VwLmJ5ID0gREYubmFtZSkgKyBOb0F4ZXMoKSkKClZsblBsb3Qoc2V1LmQsIGZlYXR1cmVzID0gIm5GZWF0dXJlX1JOQSIsIGdyb3VwLmJ5ID0gREYubmFtZSwgcHQuc2l6ZSA9IDAuMSkKCmBgYAoKCgoKUmVtb3ZlIHRoZSBkb3VibGV0IGNlbGxzCgpgYGB7cn0Kc2V1LmQgPC0gc2V1LmRbLCBzZXUuZEBtZXRhLmRhdGFbLCBERi5uYW1lXT09ICJTaW5nbGV0Il0KZGltKHNldS5kKQpkaW0oc2V1LnN1YikKCiMgMjAwMDAgcHJlIGZpbHRlcgojIGNyZWF0ZXMgdGhlIGV4cGVjdGVkIHBlcmNlbnRhZ2UKCmBgYAoKUmVwZWF0IHdvcmtmbG93IHdpdGggZG91YmxldCByZW1vdmVkIGRhdGEgYW5kIGZpbmQgY2x1c3RlcnMgZm9yIAoKYGBge3J9CnNldSA8LSBOb3JtYWxpemVEYXRhKHNldS5kLCBub3JtYWxpemF0aW9uLm1ldGhvZCA9ICJMb2dOb3JtYWxpemUiLCBzY2FsZS5mYWN0b3IgPSAxMDAwMCkKc2V1IDwtIEZpbmRWYXJpYWJsZUZlYXR1cmVzKHNldSwgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSAyMDAwKQpzZXUgPC0gU2NhbGVEYXRhKHNldSkKc2V1IDwtIFJ1blBDQShzZXUpCnNldSA8LSBSdW5VTUFQKHNldSwgcmVkdWN0aW9uID0gInBjYSIsIG4ubmVpZ2hib3JzID0gNDMsIGRpbXMgPSAxOjMwKQpEaW1QbG90KHNldSwgcmVkdWN0aW9uID0gInVtYXAiKQoKc2V1LnEgPC0gRmluZE5laWdoYm9ycyhzZXUsIGRpbXMgPSAxOjI1LCBrLnBhcmFtID0gNDMpCnNldS5xIDwtIEZpbmRDbHVzdGVycyhzZXUucSwgcmVzb2x1dGlvbiA9IGMoMCwwLjIsMC40LDAuNikpCnNldS5xIDwtIEZpbmRDbHVzdGVycyhzZXUucSwgcmVzb2x1dGlvbiA9IGMoMCwwLjA1LDAuMSwwLjgpKQpsaWJyYXJ5KGNsdXN0cmVlKQpjbHVzdHJlZShzZXUucSkKRGltUGxvdChzZXUucSwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjA1JykKRGltUGxvdChzZXUucSwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjEnKQpEaW1QbG90KHNldS5xLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuMicpCkRpbVBsb3Qoc2V1LnEsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC40JykKRGltUGxvdChzZXUucSwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjYnKQpEaW1QbG90KHNldS5xLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuOCcpCgoKCgpgYGAKTG9vayBhdCBzb21lIGV4cHJlc3Npb24gbWFya2VycyBpbiBhIGZlYXR1cmUgcGxvdAoKYGBge3J9CiMgZ2VuZXMgcmVwb3J0ZWQgdXAgaW4gQXN0cm9jeXRlcwpGZWF0dXJlUGxvdChzZXUucSwgZmVhdHVyZXMgPSBjKCJHRkFQIiwiUzEwMEIiLCJBUVA0IiwiU0xDMUEzIiwiR0pBMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFQT0UiLCJURUFEMSIsIkdTVEE0IiwiU09YOSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlZJTSIsIkhNRzIwQSIsIkFMREgxTDEiKSkKIyBhbG1vc3Qgbm8gR0ZBUCBleHByZXNzaW9uIGFuZCBsb3RzIG9mIFMxMDBCIGV2ZXJ5d2hlcmUKCmBgYAoKCgpQcmVkaWN0IGNlbGwgdHlwZXMKCmBgYHtyfQoKCiMgU05DQSBhbmQgY29udHJvbCBtaWRicmFpbiBvcmdhbm9pZHMgMTY1IGRheXMgaW4gY3VsdHVyZQpNQk8gPC0gcmVhZFJEUygiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvQVNUMjNfQnJhaW5Db21tL01CT2NsdXN0ZXJzX25hbWVzMjkwNzIwMjEucmRzIikKCiMgTWlkYnJhaW4gIEFJVzAwMiAxMjAgZGF5cyBpbiBjdWx0dXJlCkFJV01CTyA8LSByZWFkUkRTKCIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9BSVd0cmlvMTIwZGF5cy9NT2ludGVncmF0ZWRDbHVzdGVySzEyM3JlczAuOC5uYW1lc19ub3YxNl8yMDIxIikKCiMgTWlkYnJhaW4gQUlXMDAyIDYwIGRheXMgaW4gY3VsdHVyZQoKQUlXNjAgPC0gcmVhZFJEUygiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvQUlXdHJpbzYwZGF5cy9BV0kwMDJQYXJraW5LT1BpbmtLTzYwZGF5c19sYWJlbHNfMTQwNTIwMjIucmRzIikKCgojZmlyc3QgcHJlZGljdCB3aXRoIHRoZSBNQk8gZGF0YQpJZGVudHMoTUJPKSA8LSAiY2x1c3Rlcl9sYWJlbHMiCkRlZmF1bHRBc3NheShNQk8pIDwtICJSTkEiCgojIGZpbmQgdGhlIHJlZmVyZW5jZSBhbmNob3JzCnByaW50KCJmaW5kaW5nIHJlZmVyZW5jZSBhbmNob3JzIikKYW5jaG9ycyA8LSBGaW5kVHJhbnNmZXJBbmNob3JzKHJlZmVyZW5jZSA9IE1CTyAscXVlcnkgPSBzZXUucSwgZGltcyA9IDE6MjUpCnByaW50KCJnZXR0aW5nIHByZWRpY3Rpb25zIikKcHJlZGljdGlvbnMgPC0gVHJhbnNmZXJEYXRhKGFuY2hvcnNldCA9IGFuY2hvcnMsIHJlZmRhdGEgPSBNQk8kY2x1c3Rlcl9sYWJlbHMpCnNldS5xIDwtIEFkZE1ldGFEYXRhKHNldS5xLCBtZXRhZGF0YSA9IHByZWRpY3Rpb25zKQpwcmludCh0YWJsZShzZXUucSRwcmVkaWN0ZWQuaWQpKQoKSWRlbnRzKHNldS5xKSA8LSAncHJlZGljdGVkLmlkJwojIGFkZCBuZXcgZGF0YXNsb3QgZm9yIE1CTyBwcmVkaWN0ZWQgSUQgdG8gbWFrZSB0aGUgbmV4dCBwcmVkaWN0aW9uCnNldS5xJE1CT0FTVDIzLnByZWQgPC0gSWRlbnRzKHNldS5xKQpEaW1QbG90KHNldS5xLCBncm91cC5ieSA9ICdNQk9BU1QyMy5wcmVkJywgbGFiZWwgPSBUUlVFKQogCiMjIGNoZWNrIHRoZSBwcm9wb3J0aW9uIG9mIGNlbGwgdHlwZXMgcHJlZGljdGVkIGluIGVhY2ggY2x1c3Rlcgp0LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuOCwgc2V1LnEkTUJPQVNUMjMucHJlZCkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCgojIHRyeSBiYXIgY2hhcnQKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKQoKIyBjbHVzdGVycyBkb24ndCBicmVhayB1cCBieSB0aGUgcHJlZGljdGVkIGNlbGwgdHlwZXMKCiMjIyMjIyMjIyMjIyBhbm90aGVyIHByZWRpY3Rpb25zIG5vdyB1c2luZyB0aGUgQUlXIG9yZ2Fub2lkcwoKSWRlbnRzKEFJV01CTykgPC0gInJlczA4bmFtZXMiCkRlZmF1bHRBc3NheShBSVdNQk8pIDwtICJSTkEiCgphbmNob3JzIDwtIEZpbmRUcmFuc2ZlckFuY2hvcnMocmVmZXJlbmNlID0gQUlXTUJPICxxdWVyeSA9IHNldS5xLCBkaW1zID0gMToyNSkKcHJpbnQoImdldHRpbmcgcHJlZGljdGlvbnMiKQpwcmVkaWN0aW9ucyA8LSBUcmFuc2ZlckRhdGEoYW5jaG9yc2V0ID0gYW5jaG9ycywgcmVmZGF0YSA9IEFJV01CTyRyZXMwOG5hbWVzKQpzZXUucSA8LSBBZGRNZXRhRGF0YShzZXUucSwgbWV0YWRhdGEgPSBwcmVkaWN0aW9ucykKcHJpbnQodGFibGUoc2V1LnEkcHJlZGljdGVkLmlkKSkKCklkZW50cyhzZXUucSkgPC0gJ3ByZWRpY3RlZC5pZCcKIyBhZGQgbmV3IGRhdGFzbG90IGZvciBNQk8gcHJlZGljdGVkIElEIHRvIG1ha2UgdGhlIG5leHQgcHJlZGljdGlvbgpzZXUucSRNQk9BSVcucHJlZCA8LSBJZGVudHMoc2V1LnEpCkRpbVBsb3Qoc2V1LnEsIGdyb3VwLmJ5ID0gJ01CT0FJVy5wcmVkJywgbGFiZWwgPSBUUlVFKQogCiMjIGNoZWNrIHRoZSBwcm9wb3J0aW9uIG9mIGNlbGwgdHlwZXMgcHJlZGljdGVkIGluIGVhY2ggY2x1c3Rlcgp0LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuOCwgc2V1LnEkTUJPQUlXLnByZWQpKQp0LmxhYmxlcyRGcmVxIDwtIGFzLmRvdWJsZSh0LmxhYmxlcyRGcmVxKQoKIyB0cnkgYmFyIGNoYXJ0CmdncGxvdCh0LmxhYmxlcywgYWVzKHkgPSBGcmVxLCB4ID0gVmFyMSwgZmlsbCA9IFZhcjIpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdD0gImlkZW50aXR5IikKCiMgdGhlIHByZWRpY3RlZCBjZWxsIHR5cGVzIG1ha2UgbW9yZSBzZW5zZSBmcm9tIHRoZSBBSVcwMDIgb3JnYW5vaWQKIyBub3cgcHJlZGljdCB3aXRoIHRoZSBBSVcwMDIgNjAgZGF5cyBvcmdhbm9pZAoKSWRlbnRzKEFJVzYwKSA8LSAiY2x1c3Rlci5pZHMiCkRlZmF1bHRBc3NheShBSVc2MCkgPC0gIlJOQSIKCmFuY2hvcnMgPC0gRmluZFRyYW5zZmVyQW5jaG9ycyhyZWZlcmVuY2UgPSBBSVc2MCwgcXVlcnkgPSBzZXUucSwgZGltcyA9IDE6MjUpCnByaW50KCJnZXR0aW5nIHByZWRpY3Rpb25zIikKcHJlZGljdGlvbnMgPC0gVHJhbnNmZXJEYXRhKGFuY2hvcnNldCA9IGFuY2hvcnMsIHJlZmRhdGEgPSBBSVc2MCRjbHVzdGVyLmlkcykgCnNldS5xIDwtIEFkZE1ldGFEYXRhKHNldS5xLCBtZXRhZGF0YSA9IHByZWRpY3Rpb25zKQpwcmludCh0YWJsZShzZXUucSRwcmVkaWN0ZWQuaWQpKQoKSWRlbnRzKHNldS5xKSA8LSAncHJlZGljdGVkLmlkJwojIGFkZCBuZXcgZGF0YXNsb3QgZm9yIE1CTyBwcmVkaWN0ZWQgSUQgdG8gbWFrZSB0aGUgbmV4dCBwcmVkaWN0aW9uCnNldS5xJEFJVzYwLnByZWQgPC0gSWRlbnRzKHNldS5xKQpEaW1QbG90KHNldS5xLCBncm91cC5ieSA9ICdBSVc2MC5wcmVkJywgbGFiZWwgPSBUUlVFKQogCiMjIGNoZWNrIHRoZSBwcm9wb3J0aW9uIG9mIGNlbGwgdHlwZXMgcHJlZGljdGVkIGluIGVhY2ggY2x1c3Rlcgp0LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuOCwgc2V1LnEkQUlXNjAucHJlZCkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCgojIHRyeSBiYXIgY2hhcnQKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKQoKIyBzYXZlIG9qYmVjdCB3aXRoIHByZWRpY2l0b25zCnNhdmVSRFMoc2V1LnEsICIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9QaGVub0lEL3NjUk5Bc2VxU29ydGVkL29ianMvR2xpYTFQcmVkaWN0aW9uc1NldTAxMTAyMDIyLlJEUyIpCgoKCmBgYAoKCkxvb2sgYXQgdGhlIHJlZmVyZW5jZSBvYmplY3RzIAoKYGBge3J9CgojIHRyaXBsaWNhdGlvbgpEaW1QbG90KE1CTykgIyBoYXMgdHdvIGdyb3VwcyBvZiBhc3Ryb2N5dGVzCiMgQUlXIDYwIGRheXMKRGltUGxvdChBSVc2MCkgIyBoYXMgb25lIGdyb3VwIG9mIGFzdHJvY3l0ZXMKIyBBSVcgMTIwIGRheXMKRGltUGxvdChBSVdNQk8pICMgaGFzIHR3byBhc3Ryb2N5dGUgZ3JvdXBzCgoKYGBgCgpMb29rIG1vcmUgYXQgdGhlIHByZWRpY3Rpb25zCgpgYGB7cn0KCiMgQUlXMDAyIDEyMCBkYXlzIHByZWRpY3Rpb25zCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRNQk9BSVcucHJlZCkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCmdncGxvdCh0LmxhYmxlcywgYWVzKHkgPSBGcmVxLCB4ID0gVmFyMSwgZmlsbCA9IFZhcjIpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdD0gImlkZW50aXR5IikgKyBSb3RhdGVkQXhpcygpIAp0b3AucHJlZC5jZWxsdHlwZS5BSVcxMjAgPC0gYXMuZGF0YS5mcmFtZSh0LmxhYmxlcyAgJT4lIGdyb3VwX2J5KFZhcjEpICAlPiUgdG9wX24oMiwgRnJlcSkpCmRmLnRvcC5haXcxMjAgPC0gdG9wLnByZWQuY2VsbHR5cGUuQUlXMTIwW29yZGVyKHRvcC5wcmVkLmNlbGx0eXBlLkFJVzEyMCRWYXIxLC10b3AucHJlZC5jZWxsdHlwZS5BSVcxMjAkRnJlcSksXQpyb3cubmFtZXMoZGYudG9wLmFpdzEyMCkgPC0gTlVMTApkZi50b3AuYWl3MTIwJEkgPC0gcm93Lm5hbWVzKGRmLnRvcC5haXcxMjApCgojIEFJVzAwMiA2MCBkYXlzIHByZWRpY3Rpb25zCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRBSVc2MC5wcmVkKSkKdC5sYWJsZXMkRnJlcSA8LSBhcy5kb3VibGUodC5sYWJsZXMkRnJlcSkKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKSArIFJvdGF0ZWRBeGlzKCkgCnRvcC5wcmVkLmNlbGx0eXBlLkFJVzYwIDwtYXMuZGF0YS5mcmFtZSh0LmxhYmxlcyAgJT4lIGdyb3VwX2J5KFZhcjEpICAlPiUgdG9wX24oMiwgRnJlcSkpCmRmLnRvcC5haXc2MCA8LSB0b3AucHJlZC5jZWxsdHlwZS5BSVc2MFtvcmRlcih0b3AucHJlZC5jZWxsdHlwZS5BSVc2MCRWYXIxLC10b3AucHJlZC5jZWxsdHlwZS5BSVc2MCRGcmVxKSxdCnJvdy5uYW1lcyhkZi50b3AuYWl3NjApIDwtIE5VTEwKZGYudG9wLmFpdzYwJEkgPC0gcm93Lm5hbWVzKGRmLnRvcC5haXc2MCkKCgojIEFTVDIzIDE2NSBkYXlzIHByZWRpY3Rpb25zCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRNQk9BU1QyMy5wcmVkKSkKdC5sYWJsZXMkRnJlcSA8LSBhcy5kb3VibGUodC5sYWJsZXMkRnJlcSkKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKSArIFJvdGF0ZWRBeGlzKCkgCnRvcC5wcmVkLmNlbGx0eXBlLkFTVDIzIDwtIGFzLmRhdGEuZnJhbWUodC5sYWJsZXMgICU+JSBncm91cF9ieShWYXIxKSAgJT4lIHRvcF9uKDIsIEZyZXEpKQpkZi50b3AuQVNUMjMgPC0gdG9wLnByZWQuY2VsbHR5cGUuQVNUMjNbb3JkZXIodG9wLnByZWQuY2VsbHR5cGUuQVNUMjMkVmFyMSwtdG9wLnByZWQuY2VsbHR5cGUuQVNUMjMkRnJlcSksXQpyb3cubmFtZXMoZGYudG9wLkFTVDIzKSA8LSBOVUxMCmRmLnRvcC5BU1QyMyRJIDwtIHJvdy5uYW1lcyhkZi50b3AuQVNUMjMpCgpwcmVkLnRhYmxlIDwtIG1lcmdlKGRmLnRvcC5BU1QyMywgZGYudG9wLmFpdzYwLCBieSA9ICdJJywgYWxsID0gVFJVRSkKcHJlZC50YWJsZSA8LSBtZXJnZShwcmVkLnRhYmxlLCBkZi50b3AuYWl3MTIwLCBieSA9ICdJJykKcHJlZC50YWJsZQoKYGBgClRoZXNlIHByZWRpY3Rpb25zIGFyZSBub3QgZ29vZC4gIFRoZXJlIGFyZSBzZXZlcmFsIGFzdHJvY3l0ZSBtYXJrZXJzIGJ5IGV4cHJlc3Npb24gbGV2ZWxzLiAgRXZlcnl0aGluZyBpcyBwcmVkaWN0ZWQgYXMgUmFkaWFsIGdsaWEgb3Igb2xpZ28gZGVuZHJvY3l0ZXMKCgpUcnkgdG8gcHJlZGljdCB3aXRoIHRoZSBhc3Ryb2N5dGUgS2FtYXRoIGRhdGEKCmBgYHtyfQoKYXN0cm8ucmVmIDwtIHJlYWRSRFMoIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL01hY29za29fRGF0YS9QRF9hc3Ryby5SZHMiKQojIG5lZWQgdG8gbWFrZSBQQ0EgYW5kIFVNQVAKYXN0cm8ucmVmIDwtIE5vcm1hbGl6ZURhdGEoYXN0cm8ucmVmKQphc3Ryby5yZWYgPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMoYXN0cm8ucmVmLCBzZWxlY3Rpb24ubWV0aG9kID0gInZzdCIsIG5mZWF0dXJlcyA9IDIwMDApCmFzdHJvLnJlZiA8LSBTY2FsZURhdGEoYXN0cm8ucmVmKQphc3Ryby5yZWYgPC0gUnVuUENBKGFzdHJvLnJlZikKYXN0cm8ucmVmIDwtIFJ1blVNQVAoYXN0cm8ucmVmLCByZWR1Y3Rpb24gPSAicGNhIiwgbi5uZWlnaGJvcnMgPSAyMDUsIGRpbXMgPSAxOjI1KQoKY29sbmFtZXMoYXN0cm8ucmVmQG1ldGEuZGF0YSkKCgpJZGVudHMoYXN0cm8ucmVmKSA8LSAiQ2VsbF9TdWJ0eXBlIgpEZWZhdWx0QXNzYXkoYXN0cm8ucmVmKSA8LSAiUk5BIgoKIyBmaW5kIHRoZSByZWZlcmVuY2UgYW5jaG9ycwpwcmludCgiZmluZGluZyByZWZlcmVuY2UgYW5jaG9ycyIpCmFuY2hvcnMgPC0gRmluZFRyYW5zZmVyQW5jaG9ycyhyZWZlcmVuY2UgPSBhc3Ryby5yZWYgLHF1ZXJ5ID0gc2V1LnEsIGRpbXMgPSAxOjIwKQpwcmludCgiZ2V0dGluZyBwcmVkaWN0aW9ucyIpCnByZWRpY3Rpb25zIDwtIFRyYW5zZmVyRGF0YShhbmNob3JzZXQgPSBhbmNob3JzLCByZWZkYXRhID0gYXN0cm8ucmVmJENlbGxfU3VidHlwZSwgay53ZWlnaHQgPSAxMCkKc2V1LnEgPC0gQWRkTWV0YURhdGEoc2V1LnEsIG1ldGFkYXRhID0gcHJlZGljdGlvbnMpCnByaW50KHRhYmxlKHNldS5xJHByZWRpY3RlZC5pZCkpCgpJZGVudHMoc2V1LnEpIDwtICdwcmVkaWN0ZWQuaWQnCiMgYWRkIG5ldyBkYXRhc2xvdCBmb3IgTUJPIHByZWRpY3RlZCBJRCB0byBtYWtlIHRoZSBuZXh0IHByZWRpY3Rpb24Kc2V1LnEkYXN0cm8ucHJlZCA8LSBJZGVudHMoc2V1LnEpCkRpbVBsb3Qoc2V1LnEsIGdyb3VwLmJ5ID0gJ2FzdHJvLnByZWQnLCBsYWJlbCA9IFRSVUUpCnRhYmxlKHNldS5xJGFzdHJvLnByZWQpCgpzZXUucSRwcmVkaWN0ZWQuaWQgPC0gaWZlbHNlKHNldS5xJHByZWRpY3Rpb24uc2NvcmUubWF4ID4gMC45NSwgc2V1LnEkcHJlZGljdGVkLmlkLCBOQSkKcHJpbnQodGFibGUoc2V1LnEkcHJlZGljdGVkLmlkKSkKCklkZW50cyhzZXUucSkgPC0gJ3ByZWRpY3RlZC5pZCcKc2V1LnEkYXN0cm8ucHJlZC50aHJlc2ggPC0gSWRlbnRzKHNldS5xKQpEaW1QbG90KHNldS5xLCBncm91cC5ieSA9ICdhc3Ryby5wcmVkLnRocmVzaCcsIGxhYmVsID0gVFJVRSkKdGFibGUoc2V1LnEkYXN0cm8ucHJlZC50aHJlc2gpCgojIDE5OTg2IEFzdHJvX1ZJTV9UTkZTUkYxMkEgbm8gdGhyZXNob2xkICAgICAgQXN0cm9fR0xZQVRMMiAxNAojIDgzNzYgQXN0cm9fVklNX1RORlNSRjEyQSAgIHdpdGggOTUlIHRocmVzaG9sZAoKCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRhc3Ryby5wcmVkLnRocmVzaCkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCmdncGxvdCh0LmxhYmxlcywgYWVzKHkgPSBGcmVxLCB4ID0gVmFyMSwgZmlsbCA9IFZhcjIpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdD0gImlkZW50aXR5IikgKyBSb3RhdGVkQXhpcygpIAp0b3AucHJlZC5hc3RybyA8LSBhcy5kYXRhLmZyYW1lKHQubGFibGVzICAlPiUgZ3JvdXBfYnkoVmFyMSkgICU+JSB0b3BfbigyLCBGcmVxKSkKZGYudG9wLmFzdHJvIDwtIHRvcC5wcmVkLmFzdHJvW29yZGVyKHRvcC5wcmVkLmFzdHJvJFZhcjEsLXRvcC5wcmVkLmFzdHJvJEZyZXEpLF0Kcm93Lm5hbWVzKGRmLnRvcC5hc3RybykgPC0gTlVMTAoKCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRhc3Ryby5wcmVkKSkKdC5sYWJsZXMkRnJlcSA8LSBhcy5kb3VibGUodC5sYWJsZXMkRnJlcSkKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKSArIFJvdGF0ZWRBeGlzKCkgCnRvcC5wcmVkLmFzdHJvIDwtIGFzLmRhdGEuZnJhbWUodC5sYWJsZXMgICU+JSBncm91cF9ieShWYXIxKSAgJT4lIHRvcF9uKDIsIEZyZXEpKQpkZi50b3AuYXN0cm8gPC0gdG9wLnByZWQuYXN0cm9bb3JkZXIodG9wLnByZWQuYXN0cm8kVmFyMSwtdG9wLnByZWQuYXN0cm8kRnJlcSksXQpyb3cubmFtZXMoZGYudG9wLmFzdHJvKSA8LSBOVUxMCgoKCmBgYAoKCgoKCkxvb2sgYXQgY2x1c3RlciBtYXJrZXJzCgpgYGB7cn0KCklkZW50cyhzZXUucSkgPC0gJ1JOQV9zbm5fcmVzLjAuMicKQ2x1c3Rlck1hcmtlcnMgPC0gRmluZEFsbE1hcmtlcnMoc2V1LnEsIG9ubHkucG9zID0gVFJVRSkKCnRvcDUgPC0gQ2x1c3Rlck1hcmtlcnMgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3BfbihuPTUsIHd0ID0gYXZnX2xvZzJGQykKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IHRvcDUkZ2VuZSwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQoKd3JpdGUuY3N2KENsdXN0ZXJNYXJrZXJzLCIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9QaGVub0lEL3NjUk5Bc2VxU29ydGVkL0dsaWExQXN0cm9jeXRlc0NsdXN0ZXJNYXJrZXJzX25ldy5jc3YiKQoKIyBmb3IgdGhlIHJlcyAwLjYgdGhlIGxhcmdlcnMgZ3JvdXBzIDAgYW5kIDEgZG9uJ3QgaGF2ZSBncmVhdCBtYXJrZXJzIGFuZCBub25lIG9mIHRoZSBtYXJrZXJzIGFyZSByZWFsbHkgdmVyeSBnb29kLiAgCiMgSSdsbCByZXJ1biB3aXRoIHJlcyAwLjIKdW5pcXVlKHNldS5xJFJOQV9zbm5fcmVzLjAuMikKCiMgc3RpbGwgbm90IG11Y2ggYmV0dGVyCgoKCmBgYAoKCgpDaGVjayBjZWxsIHR5cGUgbWFya2VycyB3aXRoIEVucmljaFIKCmBgYHtyfQoKbGlicmFyeShlbnJpY2hSKQoKc2V0RW5yaWNoclNpdGUoIkVucmljaHIiKSAjIEh1bWFuIGdlbmVzCiMgbGlzdCBvZiBhbGwgdGhlIGRhdGFiYXNlcwoKIyBsaWJhcmllcyB3aXRoIGNlbGwgdHlwZXMKCmRiIDwtIGMoJ0FsbGVuX0JyYWluX0F0bGFzX3VwJywnRGVzY2FydGVzX0NlbGxfVHlwZXNfYW5kX1Rpc3N1ZV8yMDIxJywKICAgICAgICAnQ2VsbE1hcmtlcl9BdWdtZW50ZWRfMjAyMScsJ0F6aW11dGhfQ2VsbF9UeXBlc18yMDIxJykKCiMgZW5yaWNocihnZW5lcywgZGF0YWJhc2VzID0gTlVMTCkKCiNJJ2xsIHJ1biB0aGUgY2x1c3RlcnMgb25lIGF0IGEgdGltZQoKTjEuYzAgPC0gQ2x1c3Rlck1hcmtlcnMgJT4lIGZpbHRlcihjbHVzdGVyID09IDUgJiBhdmdfbG9nMkZDID4gMCkKZ2VuZXMgPC0gTjEuYzAkZ2VuZQoKTjEuYzAuRXIgPC0gZW5yaWNocihnZW5lcywgZGF0YWJhc2VzID0gZGIpCnBsb3RFbnJpY2goTjEuYzAuRXJbWzFdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzAuRXJbWzJdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzAuRXJbWzNdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzAuRXJbWzRdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCgpOMS5Fci5nZW5lcy4xIDwtIE4xLmMwLkVyW1sxXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjEKCk4xLkVyLmdlbmVzLjIgPC0gTjEuYzAuRXJbWzJdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMgoKTjEuRXIuZ2VuZXMuMyA8LSBOMS5jMC5FcltbM11dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4zCgoKTjEuRXIuZ2VuZXMuNCA8LSBOMS5jMC5FcltbNF1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy40CgoKCiMgY2x1c3RlciAwIC0gQ2VsbCB0eXBlIG1hcmtlciBsaWJyYXJ5IC0gQnJhaW4gYXN0cm9jeXRlIHRvcCBoaXQgYW5kIGVtYnJ5b25pYyBhc3Ryb2N5dGVzCiMgZ2VuZSBsaXN0IGluIHRlcm06IGJyYWluIGFzdHJvY3l0ZQlFRkVNUDE7TkZJQTtMSVgxO1BTQVA7S0lGMjFBO1MxMDBCO0NSWUFCO0RLSzMKIyBlbWJyeW8gYXN0cm9jeXRlcwlTT1gyO0JFWDE7SE1HQ1MxO1BUUFJaMTtMSVgxO1MxMDBCO0RLSzM7SVRNMkMKCiMgY2x1c3RlciAxIC0gc3RlbSBjZWxsIHBlcmljeXRlIChicmFpbiksIHN0ZWxhdGUsIGFzdHJvY3l0ZQoKIyBjbHVzdGVyIDIgLSBoeXBvdGhhbG11cywgZW5kb3RoZWxpYWwgY2VsbHMsIG1hY3JvcGhhZ2UKIyBlbmRvdGhlbGlhbCBDU1RCO1BSRUxJRDE7TVQxWDtDUklQMjtSSE9DO1RNRU0xNDE7TVQyQTtSUFMyODtDQ0RDODVCO0VJRjNJO1JCUDE7SUQxO0M0T1JGMztJRDM7UENCRDE7TVNYMTtQUElDCgojIGNsdXN0ZXIgMyAtIHNtb290aCBtdXNjbGUgY2VsbHMKCiMgY2x1c3RlciA0IC0gTksgY2VsbHMsIGZpYnJvYmxhc3RzCiMgTksgY2VsbHMgSVRHQjE7UkFCNUM7R1NUUDE7UERDRDU7RUVGMUIyO1RHT0xOMjtTRENCUDtNVDJBO0xESEE7U05SUEQyO1lXSEFRO1pORjMyNjtUTVNCMTA7Q0NEQzUwCiMgZmlicm9ibGFzdHMgCUNPTDNBMTtDQUxEMTtDT0w2QTMKCiMgY2x1c3RlciA1IC0gZW5kb3RoZWxpYWwgY2VsbHMsIE5LIGNlbGxzLCBDRDgrCgojIGNsdXN0ZXIgNiAtIHN0cm9tYWwgY2VsbHMgZXVyeXRocm9ibGFzdHMsIG5vbmUtbmV1cm9uYWwsIG9saWdvCgojIHJlcmFuIGFuZCBub3cgdGhlcmUgYXJlIG9ubHkgNSBjbHVzdGVycwojIHJlcGVhdCBjaGVja2luZwoKCmBgYAoKQ2x1c3RlciAwIC0gYXN0cm9jeXRlcwpDbHVzdGVyIDEgLSBwZXJpY3l0ZSBhc3Ryb2N5dGUgKHdlYWsgc3RpbGwpCkNsdXN0ZXIgMiAtIGVuZG90aGVsaWFsCkNsdXN0ZXIgMyAtIHNtb290aCBtdXNjbGUKQ2x1c3RlciA0IC0gTksvZmlicm9ibGFzdApDbHVzdGVyIDUgLSBlbmRvdGhlbGlhbApDbHVzdGVyIDYgLSBub24tIG5ldXJvbmFsCgoKCgoKCgpgYGB7cn0KClZsblBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gYygiQ0Q0NCIsIklUR0IxIiwiUzEwMEIiKSwgZ3JvdXAuYnkgPSAnb3JpZy5pZGVudCcpClZsblBsb3Qoc2V1LmZ0LCBmZWF0dXJlcyA9IGMoIkNENDQiLCJJVEdCMSIsIlMxMDBCIiksIGdyb3VwLmJ5ID0gJ29yaWcuaWRlbnQnKQoKYGBgCgpDaGVjayBleHByZXNzaW9uIG9mIGtub3duIG1hcmtlcnMKCmBgYHtyfQoKSWRlbnRzKHNldS5xKSA8LSAnUk5BX3Nubl9yZXMuMC4yJwoKZmVhdHVyZV9saXN0ID0gYygiTUtJNjciLCJTT1gyIiwiUE9VNUYxIiwiRExYMiIsIlBBWDYiLCJTT1g5IiwiSEVTMSIsIk5FUyIsIlJCRk9YMyIsIk1BUDIiLCJOQ0FNMSIsIkNEMjQiLCJHUklBMiIsIkdSSU4yQiIsIkdBQkJSMSIsIkdBRDEiLCJHQUQyIiwiR0FCUkExIiwiR0FCUkIyIiwiVEgiLCJBTERIMUExIiwiTE1YMUIiLCJOUjRBMiIsIkNPUklOIiwiQ0FMQjEiLCJLQ05KNiIsIkNYQ1I0IiwiSVRHQTYiLCJTTEMxQTMiLCJDRDQ0IiwiQVFQNCIsIlMxMDBCIiwgIlBER0ZSQSIsIk9MSUcyIiwiTUJQIiwiQ0xETjExIiwiVklNIiwiVkNBTTEiKQoKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IGZlYXR1cmVfbGlzdCwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IGZlYXR1cmVfbGlzdCkgK1JvdGF0ZWRBeGlzKCkKClBEX3BvdWxpbiA9IGMoIlRIIiwiU0xDNkEzIiwiU0xDMThBMiIsIlNPWDYiLCJORE5GIiwiU05DRyIsIkFMREgxQTEiLCJDQUxCMSIsIlRBQ1IyIiwiU0xDMTdBNiIsIlNMQzMyQTEiLCJPVFgyIiwiR1JQIiwiTFBMIiwiQ0NLIiwiVklQIikKCkRvSGVhdG1hcChzZXUucSwgZmVhdHVyZXMgPSBQRF9wb3VsaW4sIHNpemU9MywgYW5nbGUgPTkwLCBncm91cC5iYXIuaGVpZ2h0ID0gMC4wMikKRG90UGxvdChzZXUucSwgZmVhdHVyZXMgPSBQRF9wb3VsaW4pK1JvdGF0ZWRBeGlzKCkKCmVhbHJ5TmV1ciA9IGMoIkRDWCIsIk5FVVJPRDEiLCJUQlIxIikKcHJvbGlmZXJhdGlvbiA9IGMoIlBDTkEiLCJNS0k2NyIpCm5ldXJhbHN0ZW0gPSBjKCJTT1gyIiwiTkVTIiwiUEFYNiIsIk1BU0gxIikKCmZlYXR1cmVfbGlzdCA8LSBjKCJEQ1giLCJORVVST0QxIiwiVEJSMSIsIlBDTkEiLCJNS0k2NyIsIlNPWDIiLCJORVMiLCJQQVg2IiwiTUFTSDEiKQpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gZmVhdHVyZV9saXN0LCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIpCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gZmVhdHVyZV9saXN0KStSb3RhdGVkQXhpcygpCgoKbWF0X25ldXJvbiA9IGMoIlJCRk9YMyIsIlNZUCIsIkRMRzQ1IiwiVkFNUDEiLCJWQU1QMiIsIlRVQkIzIiwiU1lUMSIsIkJTTiIsIkhPTUVSMSIsIlNMQzE3QTYiKSAKIyBOZXVOIGlzIEZPWDMgLSBSQkZPWDMKIyBQU0Q5NSBhbHNvIFNQLTkwIG9yIERMRzQKIyBWR0xVVDIgaXMgU0xDMTdBNgpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gbWF0X25ldXJvbiwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQojIGNsdXN0ZXIgNCBhbHNvIHNob3cgbWF0dXJlIG5ldXJvbiBtYXJrZXJzCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gbWF0X25ldXJvbikrUm90YXRlZEF4aXMoKQojIGV4Y2l0YXRvcnkgbmV1cm9uIG1hcmtlcnMKZXggPSBjKCJHUklBMiIsIkdSSUExIiwiR1JJQTQiLCJHUklOMSIsIkdSSU4yQiIsIkdSSU4yQSIsIkdSSU4zQSIsIkdSSU4zIiwiR1JJUDEiLCJDQU1LMkEiKQpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gZXgsIHNpemU9MywgYW5nbGUgPTkwLCBncm91cC5iYXIuaGVpZ2h0ID0gMC4wMikKRG90UGxvdChzZXUucSwgZmVhdHVyZXMgPSBleCkrUm90YXRlZEF4aXMoKQojIGluaGliaXRvcnkgbmV1cm9uIG1hcmtlcnMKaW5oID0gYygiR0FEMSIsIkdBRDIiLCAiR0FUMSIsIlBWQUxCIiwiR0FCUjIiLCJHQUJSMSIsIkdCUlIxIiwiR0FCUkIyIiwiR0FCUkIxIiwiR0FCUkIzIiwiR0FCUkE2IiwiR0FCUkExIiwiR0FCUkE0IiwiVFJBSzIiKQpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gaW5oLCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIpCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gaW5oKStSb3RhdGVkQXhpcygpCiMgY2x1c3RlciA0IGlzIG1vcmUgZXhjaXRhdG9yeSB0aGFuIGluaGJpdG9yeSBidXQgbmVpdGhlciBtYXJrZXIgc2V0IGhhcyBtdWNoIGV4cHJlc3Npb24gCgojIyMgZ2xpYSBtYXJrZXJzCm1pY3JvZ2xpYSA9IGMoIlBUUFJDIiwiQUlGMSIsIkFER1JFMSIpICAjIEFER1JFMSBpcyBhIG1pY3JvZ2xpYSBtYXJrZXIgRjQvODAsIENENDUgaXMgUFRQUkMsIGdlbmUgbmFtZSBJQkExIGlzIEFJRjEKYXN0b2xnTlBDcHJvbWljcm8gPSBjKCJHRkFQIiwiUzEwMEIiLCJTTEMxQTIiLCJNQlAiLCJTT1gxMCIsIlNQUDEiLCJEQ1giLCJORVVST0QxIiwiVEJSMSIsIlBDTkEiLCJNS0k2NyIsIlBUUFJDIiwiQUlGMSIsIkFER1JFMSIpCiMgbm90ZSBHTFQxIGlzIEVBQVQyIHdoaWNoIGlzIFNMQzFBMiBnbHV0YXRtYXRlIHRyYW5zcG9ydGVyCiMgZXBpdGhlbGlhbAplcGkgPSBjKCJIRVMxIiwiSEVTNSIsIlNPWDIiLCJTT1gxMCIsIk5FUyIsIkNESDEiLCJOT1RDSDEiKSAjIGUtY2FkaGVyaW4gaXMgQ0RIMQoKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IGFzdG9sZ05QQ3Byb21pY3JvLCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIpCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gYXN0b2xnTlBDcHJvbWljcm8pK1JvdGF0ZWRBeGlzKCkKIyBjbHVzdGVyIDQgaXMgbW9yZSBleGNpdGF0b3J5IHRoYW4gaW5oYml0b3J5IGJ1dCBuZWl0aGVyIG1hcmtlciBzZXQgaGFzIG11Y2ggZXhwcmVzc2lvbiAKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IGVwaSwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IGVwaSkrUm90YXRlZEF4aXMoKQoKIyBhbHNvIGFkZCBSYWRpYWwgZ2xpYSBtYXJrZXIgb3ZlcmxhcCB3aXRoIEdsaWEgYW5kIE5ldXJvbnMKCmZlYXR1cmVzIDwtIGMoIlBUUFJDIiwiQUlGMSIsIkFER1JFMSIsICJWSU0iLCAiVE5DIiwiUFRQUloxIiwiRkFNMTA3QSIsIkhPUFgiLCJMSUZSIiwKICAgICAgICAgICAgICAiSVRHQjUiLCJJTDZTVCIpCkRvSGVhdG1hcChzZXUucSwgZmVhdHVyZXMgPSBmZWF0dXJlcywgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IGZlYXR1cmVzKStSb3RhdGVkQXhpcygpCgoKCgpgYGAKCk5vIFRIIGV4cHJlc3Npb24KCmNsdXN0ZXJzIDUgVklNIGhpZ2hlc3QsIFMxMDAgQiAKQ2x1c3RlciA0IApDbHVzdGVyIDMgaGFzIHNvbWUgY2VsbHMgd2l0aCBoaWdoIE9UWDIsIE5FUyBpbmRpY2F0ZXMgTlBDL1ByZWN1cnNvcnMKQ2x1c3RlciAyIGhhcyBzb21lIFNPWDIgYW5kIFBBWDYgaW5kaWNhdGVzIE5QQywgVkFNUDIgaW5kaWNhdGluZyBuZXVyb25zLCBTMTAwQiBoaWdoZXN0IGFuZCBtb3N0IC0gaW5kaWNhdGVzIGFzdHJvY3l0ZXMsIGFsc28gTUJQIGluZGljYXRlcyBvbGlnb3MKQ2x1c3RlciAxCkNsdXN0ZXIgMCAKCgpMYWJsZSB0aGUgY2x1c3RlcnMgCgpgYGB7cn0KCklkZW50cyhzZXUucSkgPC0gJ1JOQV9zbm5fcmVzLjAuMicKCiNzZXUucSA8LSBCdWlsZENsdXN0ZXJUcmVlKHNldS5xLCByZW9yZGVyID0gVFJVRSwgcmVvcmRlci5udW1lcmljID0gVFJVRSkKdW5pcXVlKHNldS5xJFJOQV9zbm5fcmVzLjAuMikKCmNsdXN0ZXIuaWRzIDwtIGMoIkFzdHJvY3l0ZXMxIiwiQXN0cm9jeXRlczIiLCJQcmVjdXJzb3JzIiwiUkcxIiwiUkcyIiwiRW5kb3RoZWxpYWwiKQoKbmFtZXMoY2x1c3Rlci5pZHMpIDwtIGxldmVscyhzZXUucSkKc2V1LnEgPC0gUmVuYW1lSWRlbnRzKHNldS5xLCBjbHVzdGVyLmlkcykKc2V1LnEkc3ViZ3JvdXBzIDwtIElkZW50cyhzZXUucSkKCiNEaW1QbG90KHNldS5xLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjInLCBsYWJlbCA9IFRSVUUpCkRpbVBsb3Qoc2V1LnEsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgbGFiZWwgPSBUUlVFLCBncm91cC5ieSA9ICdzdWJncm91cHMnLCByZXBlbCA9IFRSVUUpCgojIHNvbWV0aGluZyB3ZWlyZCBpcyBnb2luZyBvbiBpbiB0aGUgb3JkZXIKCiNzYXZlUkRTKHNldS5xLCAiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvUGhlbm9JRC9zY1JOQXNlcVNvcnRlZC9vYmpzL0dsaWExTGFibGVkU2V1MzAxMTAyMDIyLlJEUyIpCgoKYGBgCgoKCkNvbXBhcmUgdGhlIEFzdHJvY3l0ZSBncm91cHMgYW5kIGdldCBzb21lIG1hcmtlcnMgZm9yIHN1YiBncm91cHMKCmBgYHtyfQoKCmFzdHJvLnN1Yi5tYXJrZXJzIDwtIEZpbmRNYXJrZXJzKHNldS5xLCBpZGVudC4xID0gIkFzdHJvY3l0ZXMxIiwgaWRlbnQuMiA9ICJBc3Ryb2N5dGVzMiIsIG9ubHkucG9zID0gRkFMU0UpCiN0b3A1IDwtIGFzdHJvLnN1Yi5tYXJrZXJzICU+JSB0b3BfbihuPTUsIHd0ID0gYXZnX2xvZzJGQykKCkRvSGVhdG1hcChzZXUucSwgZmVhdHVyZXMgPSBjKCJQTENHMiIsIlBUUFJaMSIsIlNOSEcyNSIsIlZDQU4iLCJMVU0iLCJEQ04iLCJTMTAwNEEiKSwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQoKYXN0cm8yIDwtIHJvd25hbWVzKGFzdHJvLnN1Yi5tYXJrZXJzICU+JSBmaWx0ZXIoYXZnX2xvZzJGQyA8IDAuMDUpKQoKRG90UGxvdChzZXUucSwgZmVhdHVyZXMgPSBjKCJQTENHMiIsIlBUUFJaMSIsIlNOSEcyNSIsIlZDQU4iLCJMVU0iLCJEQ04iLCJTMTAwNEEiKSkgKyBSb3RhdGVkQXhpcygpCgpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gYXN0cm8yWzE6MTVdLCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIpCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gYXN0cm8yWzE6MTVdKSArUm90YXRlZEF4aXMoKQoKCiMgcmFkaWFsIGdsaWEgc3VidHlwaW5nCklkZW50cyhzZXUucSkgPC0gKCdzdWJncm91cHMnKQpyZy5zdWIubWFya2VycyA8LSBGaW5kTWFya2VycyhzZXUucSwgaWRlbnQuMSA9ICJSRzEiLCBpZGVudC4yID0gIlJHMiIsIG9ubHkucG9zID0gRkFMU0UpCnRvcDUudXAgPC0gcmcuc3ViLm1hcmtlcnMgJT4lIHRvcF9uKG49MTAsIHd0ID0gYXZnX2xvZzJGQykKdG9wNS5kb3duIDwtIHJnLnN1Yi5tYXJrZXJzICU+JSB0b3BfbihuPS0xMCwgd3QgPSBhdmdfbG9nMkZDKQpmdCA8LSByb3duYW1lcyh0b3A1LnVwKQoKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IGZ0LCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIpCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gZnQpICsgUm90YXRlZEF4aXMoKQoKCmZ0IDwtIHJvd25hbWVzKHRvcDUuZG93bikKCkRvSGVhdG1hcChzZXUucSwgZmVhdHVyZXMgPSBmdCwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IGZ0KSArIFJvdGF0ZWRBeGlzKCkKCm5wYy5tYXJrZXJzIDwtIEZpbmRNYXJrZXJzKHNldS5xLCBpZGVudC4xID0gIlByZWN1cnNvcnMiLCBpZGVudC4yID0gYygiQXN0cm9jeXRlczIiLCJBc3Ryb2N5dGVzMSIpLCBvbmx5LnBvcyA9IEZBTFNFKQp0b3AxMC5ucGMgPC0gbnBjLm1hcmtlcnMgJT4lIHRvcF9uKG49MTAsIHd0ID0gYXZnX2xvZzJGQykKbnBjLm1hcmtlcnMgPC0gbnBjLm1hcmtlcnMgJT4lIGZpbHRlcihhdmdfbG9nMkZDID4gMCkKZGltKG5wYy5tYXJrZXJzKQoKZnQgPC0gcm93bmFtZXModG9wMTAubnBjKQojIGNvbnNpZGVyIG5hbWluZyBwcmVjdXJzb3JzIGFzIGFzdHJvY3l0ZXMzCkRvSGVhdG1hcChzZXUucSwgZmVhdHVyZXMgPSBmdCwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IGZ0KSArIFJvdGF0ZWRBeGlzKCkKCgpucGMubWFya2Vycy5yZyA8LSBGaW5kTWFya2VycyhzZXUucSwgaWRlbnQuMSA9ICJQcmVjdXJzb3JzIiwgaWRlbnQuMiA9IGMoIlJHMiIsIlJHMSIpLCBvbmx5LnBvcyA9IFRSVUUpCnRvcDEwLm5wYyA8LSBucGMubWFya2Vycy5yZyAlPiUgdG9wX24obj0xMCwgd3QgPSBhdmdfbG9nMkZDKQoKZnQgPC0gcm93bmFtZXModG9wMTAubnBjKQojIGNvbnNpZGVyIG5hbWluZyBwcmVjdXJzb3JzIGFzIGFzdHJvY3l0ZXMzCkRvSGVhdG1hcChzZXUucSwgZmVhdHVyZXMgPSBmdCwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IGZ0KSArIFJvdGF0ZWRBeGlzKCkKCiMjIHRoZXNlIGhhdmUgbW9yZSBkaWZmZXJlbmNlcyBmcm9tIFJHIHRoYW4gQXN0cm9jeXRlcwoKCmBgYAoKQWRkIHN1YnR5cGUgZ2VuZSBpZHMKCmBgYHtyfQoKRGltUGxvdChzZXUucSwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC4yJykKCmNsdXN0ZXIuaWRzIDwtIGMoIkFzdHJvY3l0ZXMtUExDRzIiLCJBc3Ryb2N5dGVzLUROQyIsIkFzdHJvY3l0ZXMtSUdGQlAyIiwKICAgICAgICAgICAgICAgICAiUkcxLUNES04xQyIsIlJHMi1UWVJQMSIsIkVuZG90aGVsaWFsIikKI2NsdXN0ZXIuaWRzIDwtIGMoIkFzdHJvY3l0ZXMxIiwiQXN0cm9jeXRlczIiLCJQcmVjdXJzb3JzKEFzdHJvY3l0ZXMpIiwiUkcxIiwiUkcyIiwiRW5kb3RoZWxpYWwiKQoKbmFtZXMoY2x1c3Rlci5pZHMpIDwtIGxldmVscyhzZXUucSkKc2V1LnEgPC0gUmVuYW1lSWRlbnRzKHNldS5xLCBjbHVzdGVyLmlkcykKc2V1LnEkQ2VsbF90eXBlcyA8LSBJZGVudHMoc2V1LnEpCgpEaW1QbG90KHNldS5xLCByZWR1Y3Rpb24gPSAidW1hcCIsIGxhYmVsID0gVFJVRSwgZ3JvdXAuYnkgPSAnQ2VsbF90eXBlcycsIHJlcGVsID0gVFJVRSkKCgpzYXZlUkRTKHNldS5xLCAiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvUGhlbm9JRC9zY1JOQXNlcVNvcnRlZC9vYmpzL0dsaWExTGFibGVkU2V1MzAxMTAyMDIyLlJEUyIpCgojIGxhYmVsIHdpdGggbWFpbiBjZWxsIHR5cGUgZ3JvdXBzIAoKRGltUGxvdChzZXUucSwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC4yJykKCmNsdXN0ZXIuaWRzIDwtIGMoIkFzdHJvY3l0ZXMiLCJBc3Ryb2N5dGVzIiwiQXN0cm9jeXRlcyIsCiAgICAgICAgICAgICAgICAgIlJHIiwiUkciLCJFbmRvdGhlbGlhbCIpCiNjbHVzdGVyLmlkcyA8LSBjKCJBc3Ryb2N5dGVzMSIsIkFzdHJvY3l0ZXMyIiwiUHJlY3Vyc29ycyhBc3Ryb2N5dGVzKSIsIlJHMSIsIlJHMiIsIkVuZG90aGVsaWFsIikKCm5hbWVzKGNsdXN0ZXIuaWRzKSA8LSBsZXZlbHMoc2V1LnEpCnNldS5xIDwtIFJlbmFtZUlkZW50cyhzZXUucSwgY2x1c3Rlci5pZHMpCnNldS5xJENlbGxfVHlwZSA8LSBJZGVudHMoc2V1LnEpCgpEaW1QbG90KHNldS5xLCByZWR1Y3Rpb24gPSAidW1hcCIsIGxhYmVsID0gVFJVRSwgZ3JvdXAuYnkgPSAnQ2VsbF9UeXBlJywgcmVwZWwgPSBUUlVFKQoKCnNhdmVSRFMoc2V1LnEsICIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9QaGVub0lEL3NjUk5Bc2VxU29ydGVkL29ianMvR2xpYTFMYWJsZWRTZXUzMDExMDIwMjIuUkRTIikKCgoKCmBgYAoKClByb3BvcnRpb25zIG9mIGNlbGxzIHR5cGVzCgpgYGB7cn0KCgoKYGBgCgoKUXVpY2sgY2hlY2sgdGhlIEdsaWFsMiAKCmBgYHtyfQoKIyBleHBsb3JlIGZpbHRlcmluZwpzZXUgPC0gR2xpYTIKc2V1CiMgClZsblBsb3Qoc2V1LCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIG5jb2wgPSAzKQoKVmxuUGxvdChzZXUsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIpLCB5Lm1heCA9IDEwMDApClZsblBsb3Qoc2V1LCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiKSwgeS5tYXggPSA1MDApClZsblBsb3Qoc2V1LCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuQ291bnRfUk5BIiksIHkubWF4ID0gMjAwMCkKCiMgZmlsdGVyIG1vcmUgY2VsbHMKCnNldS5mdCA8LSBzdWJzZXQoc2V1LCBzdWJzZXQgPSBuRmVhdHVyZV9STkEgPiAyNTAgJiBuQ291bnRfUk5BID4gMjUwICYgbkNvdW50X1JOQSA8IDEwMDAwKSAKc2V1LmZ0CgpWbG5QbG90KHNldS5mdCwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiksIHkubWF4ID0gMjAwMCkKCmBgYApgYGB7cn0KClZsblBsb3Qoc2V1LmZ0LmdsaWEsIGZlYXR1cmVzID0gYygiQ0Q0NCIsIlMxMDBCIiwiSVRHQjEiKSkKVmxuUGxvdChzZXUuZnQsIGZlYXR1cmVzID0gYygiQ0Q0NCIsIlMxMDBCIiwiSVRHQjEiKSwgZ3JvdXAuYnkgPSAnb3JpZy5pZGVudCcpCiMgYm90aCBnbGlhIHBvcHVsYXRpb25zIGFyZSBzaW1pbGFyCgoKYGBgCgpMZXZlbHMgc2VlbSBzaW1pbGFyIGluIEdsaWExIGFuZCBHbGlhMgoKUmVtb3ZlIGRvdWJsZXRzIGFuZCBzdGFydCB0byBwcm9jZXNzIEdsaWEgMgoKYGBge3J9CgpzdXBwcmVzc01lc3NhZ2VzKHJlcXVpcmUoRG91YmxldEZpbmRlcikpCgojIGZpbHRlcmluZyBvdXQgTUFMQVQxIGFuZCBtaXRvY2hvbmRyaWFsIGdlbmVzCgpzZXUuZnQgPC0gc2V1LmZ0WyFncmVwbCgiTUFMQVQxIiwgcm93bmFtZXMoc2V1LmZ0KSksIF0Kc2V1LmZ0IDwtIHNldS5mdFshZ3JlcGwoIl5NVC0iLCByb3duYW1lcyhzZXUuZnQpKSwgXQoKIyBsaWtlIGluIHRoZSB0dXRvcmlhbCBJJ20gZm9sbG93aW5nIE1BTEFUMSBpcyB0aGUgdG9wIG1vc3QgZXhwcmVzc2VkIGdlbmUuICBUaGUgdG9wIGdlbmVzIGFyZSBhIGxvdCBvZiBNVCBhbmQgUmlib3NvbWFsIGdlbmVzCgpzZXUuZnRbWyJwZXJjZW50LnJiIl1dIDwtIFBlcmNlbnRhZ2VGZWF0dXJlU2V0KHNldS5mdCwgcGF0dGVybiA9ICJeUlAiKQoKc2V1LmQgPSBOb3JtYWxpemVEYXRhKHNldS5mdCkKc2V1LmQgPSBGaW5kVmFyaWFibGVGZWF0dXJlcyhzZXUuZCwgdmVyYm9zZSA9IEYpCnNldS5kID0gU2NhbGVEYXRhKHNldS5kLCB2YXJzLnRvLnJlZ3Jlc3MgPSBjKCJuRmVhdHVyZV9STkEiLCAicGVyY2VudC5tdCIpLAogICAgdmVyYm9zZSA9IEYpCnNldS5kID0gUnVuUENBKHNldS5kLCB2ZXJib3NlID0gRiwgbnBjcyA9IDE1KQpzZXUuZCA9IFJ1blVNQVAoc2V1LmQsIGRpbXMgPSAxOjEwLCB2ZXJib3NlID0gRikKCm5FeHAgPC0gcm91bmQobmNvbChzZXUuZCkgKiAwLjA4KSAgIyBleHBlY3QgbW9yZSBkb3VibGV0cyBiZWNhdXNlIHRoZXJlIGlzIGEgbG90IG1vcmUgY2VsbHMKc2V1LmQgPC0gZG91YmxldEZpbmRlcl92MyhzZXUuZCwgcE4gPSAwLjI1LCBwSyA9IDAuMDksIG5FeHAgPSBuRXhwLCBQQ3MgPSAxOjEwKQojIHRoZSBtZW1vcnkgbGltaXQgaXMgcmVhY2hlZCBoZXJlIC0gSSBjb3VsZCBydW4gb24gY29tcHV0ZSBjYW5hZGEKIyBGb3Igbm93IEknbGwgZG93bnNhbXBsZQojIHRoaXMgd29ya3MKCiMgbmFtZSBvZiB0aGUgREYgcHJlZGljdGlvbiBjYW4gY2hhbmdlLCBzbyBleHRyYWN0IHRoZSBjb3JyZWN0IGNvbHVtbiBuYW1lLgpERi5uYW1lID0gY29sbmFtZXMoc2V1LmRAbWV0YS5kYXRhKVtncmVwbCgiREYuY2xhc3NpZmljYXRpb24iLCBjb2xuYW1lcyhzZXUuZEBtZXRhLmRhdGEpKV0KCgpjb3dwbG90OjpwbG90X2dyaWQobmNvbCA9IDIsIERpbVBsb3Qoc2V1LmQsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKSArIE5vQXhlcygpLAogICAgRGltUGxvdChzZXUuZCwgZ3JvdXAuYnkgPSBERi5uYW1lKSArIE5vQXhlcygpKQoKVmxuUGxvdChzZXUuZCwgZmVhdHVyZXMgPSAibkZlYXR1cmVfUk5BIiwgZ3JvdXAuYnkgPSBERi5uYW1lLCBwdC5zaXplID0gMC4xKQoKYGBgCgoKYGBge3J9CgpzZXUuZCA8LSBzZXUuZFssIHNldS5kQG1ldGEuZGF0YVssIERGLm5hbWVdPT0gIlNpbmdsZXQiXQpkaW0oc2V1LmQpCmRpbShzZXUuZnQpCgoKCmBgYAoKQ2x1c3RlciAKCmBgYHtyfQpzZXUgPC0gTm9ybWFsaXplRGF0YShzZXUuZCwgbm9ybWFsaXphdGlvbi5tZXRob2QgPSAiTG9nTm9ybWFsaXplIiwgc2NhbGUuZmFjdG9yID0gMTAwMDApCnNldSA8LSBGaW5kVmFyaWFibGVGZWF0dXJlcyhzZXUsIHNlbGVjdGlvbi5tZXRob2QgPSAidnN0IiwgbmZlYXR1cmVzID0gMjAwMCkKc2V1IDwtIFNjYWxlRGF0YShzZXUpCnNldSA8LSBSdW5QQ0Eoc2V1KQpzZXUgPC0gUnVuVU1BUChzZXUsIHJlZHVjdGlvbiA9ICJwY2EiLCBuLm5laWdoYm9ycyA9IDI1LCBkaW1zID0gMTozMCkKRGltUGxvdChzZXUsIHJlZHVjdGlvbiA9ICJ1bWFwIikKCnNldS5xIDwtIEZpbmROZWlnaGJvcnMoc2V1LCBkaW1zID0gMToyNSwgay5wYXJhbSA9IDI1KQpzZXUucSA8LSBGaW5kQ2x1c3RlcnMoc2V1LnEsIHJlc29sdXRpb24gPSBjKDAsMC4wNSwwLjIsMC40LDAuNSwwLjYsMC44KSkKbGlicmFyeShjbHVzdHJlZSkKCkRpbVBsb3Qoc2V1LnEsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC4wNScpCkRpbVBsb3Qoc2V1LnEsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC4xJykKRGltUGxvdChzZXUucSwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjInKQpEaW1QbG90KHNldS5xLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuNCcpCkRpbVBsb3Qoc2V1LnEsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC42JykKRGltUGxvdChzZXUucSwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjgnKQpjbHVzdHJlZShzZXUucSkKIyAwLjQgaXMgbGlrZWx5IHRoZSBiZXN0IGFubm90YXRlIHN1Ymdyb3VwcwoKCmBgYAoKUHJlZGljdCBjZWxsIHR5cGVzIAoKCmBgYHtyfQoKIyBTTkNBIGFuZCBjb250cm9sIG1pZGJyYWluIG9yZ2Fub2lkcyAxNjUgZGF5cyBpbiBjdWx0dXJlCk1CTyA8LSByZWFkUkRTKCIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9BU1QyM19CcmFpbkNvbW0vTUJPY2x1c3RlcnNfbmFtZXMyOTA3MjAyMS5yZHMiKQoKIyBNaWRicmFpbiAgQUlXMDAyIDEyMCBkYXlzIGluIGN1bHR1cmUKQUlXTUJPIDwtIHJlYWRSRFMoIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL0FJV3RyaW8xMjBkYXlzL01PaW50ZWdyYXRlZENsdXN0ZXJLMTIzcmVzMC44Lm5hbWVzX25vdjE2XzIwMjEiKQoKIyBNaWRicmFpbiBBSVcwMDIgNjAgZGF5cyBpbiBjdWx0dXJlCgpBSVc2MCA8LSByZWFkUkRTKCIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9BSVd0cmlvNjBkYXlzL0FXSTAwMlBhcmtpbktPUGlua0tPNjBkYXlzX2xhYmVsc18xNDA1MjAyMi5yZHMiKQoKCiNmaXJzdCBwcmVkaWN0IHdpdGggdGhlIE1CTyBkYXRhCklkZW50cyhNQk8pIDwtICJjbHVzdGVyX2xhYmVscyIKRGVmYXVsdEFzc2F5KE1CTykgPC0gIlJOQSIKCiMgZmluZCB0aGUgcmVmZXJlbmNlIGFuY2hvcnMKcHJpbnQoImZpbmRpbmcgcmVmZXJlbmNlIGFuY2hvcnMiKQphbmNob3JzIDwtIEZpbmRUcmFuc2ZlckFuY2hvcnMocmVmZXJlbmNlID0gTUJPICxxdWVyeSA9IHNldS5xLCBkaW1zID0gMToyNSkKcHJpbnQoImdldHRpbmcgcHJlZGljdGlvbnMiKQpwcmVkaWN0aW9ucyA8LSBUcmFuc2ZlckRhdGEoYW5jaG9yc2V0ID0gYW5jaG9ycywgcmVmZGF0YSA9IE1CTyRjbHVzdGVyX2xhYmVscykKc2V1LnEgPC0gQWRkTWV0YURhdGEoc2V1LnEsIG1ldGFkYXRhID0gcHJlZGljdGlvbnMpCgpJZGVudHMoc2V1LnEpIDwtICdwcmVkaWN0ZWQuaWQnCiMgYWRkIG5ldyBkYXRhc2xvdCBmb3IgTUJPIHByZWRpY3RlZCBJRCB0byBtYWtlIHRoZSBuZXh0IHByZWRpY3Rpb24Kc2V1LnEkTUJPQVNUMjMucHJlZCA8LSBJZGVudHMoc2V1LnEpCkRpbVBsb3Qoc2V1LnEsIGdyb3VwLmJ5ID0gJ01CT0FTVDIzLnByZWQnLCBsYWJlbCA9IFRSVUUpCgojIHNlZSBob3cgYWNjdXJhdGUgdGhlIHByZWRpY3Rpb25zIGFyZQpzZXUucSRwcmVkaWN0ZWQuaWQgPC0gaWZlbHNlKHNldS5xJHByZWRpY3Rpb24uc2NvcmUubWF4ID4gMC45NSwgc2V1LnEkcHJlZGljdGVkLmlkLCAiTm9uZSIpCgpJZGVudHMoc2V1LnEpIDwtICdwcmVkaWN0ZWQuaWQnCnNldS5xJE1CT0FTVDIzLnRocmVzaCA8LSBJZGVudHMoc2V1LnEpCkRpbVBsb3Qoc2V1LnEsIGdyb3VwLmJ5ID0gJ3ByZWRpY3RlZC5pZCcsIGxhYmVsID0gVFJVRSkKdGFibGUoc2V1LnEkTUJPQVNUMjMucHJlZCkKdGFibGUoc2V1LnEkTUJPQVNUMjMudGhyZXNoKQoKCiAKIyMgY2hlY2sgdGhlIHByb3BvcnRpb24gb2YgY2VsbCB0eXBlcyBwcmVkaWN0ZWQgaW4gZWFjaCBjbHVzdGVyCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC40LCBzZXUucSRNQk9BU1QyMy5wcmVkKSkKdC5sYWJsZXMkRnJlcSA8LSBhcy5kb3VibGUodC5sYWJsZXMkRnJlcSkKCiMgdHJ5IGJhciBjaGFydApnZ3Bsb3QodC5sYWJsZXMsIGFlcyh5ID0gRnJlcSwgeCA9IFZhcjEsIGZpbGwgPSBWYXIyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ICJpZGVudGl0eSIpCgojIGNsdXN0ZXJzIGRvbid0IGJyZWFrIHVwIGJ5IHRoZSBwcmVkaWN0ZWQgY2VsbCB0eXBlcwoKIyMjIyMjIyMjIyMjIGFub3RoZXIgcHJlZGljdGlvbnMgbm93IHVzaW5nIHRoZSBBSVcgb3JnYW5vaWRzCgpJZGVudHMoQUlXTUJPKSA8LSAicmVzMDhuYW1lcyIKRGVmYXVsdEFzc2F5KEFJV01CTykgPC0gIlJOQSIKCmFuY2hvcnMgPC0gRmluZFRyYW5zZmVyQW5jaG9ycyhyZWZlcmVuY2UgPSBBSVdNQk8gLHF1ZXJ5ID0gc2V1LnEsIGRpbXMgPSAxOjI1KQpwcmludCgiZ2V0dGluZyBwcmVkaWN0aW9ucyIpCnByZWRpY3Rpb25zIDwtIFRyYW5zZmVyRGF0YShhbmNob3JzZXQgPSBhbmNob3JzLCByZWZkYXRhID0gQUlXTUJPJHJlczA4bmFtZXMpCnNldS5xIDwtIEFkZE1ldGFEYXRhKHNldS5xLCBtZXRhZGF0YSA9IHByZWRpY3Rpb25zKQpwcmludCh0YWJsZShzZXUucSRwcmVkaWN0ZWQuaWQpKQoKSWRlbnRzKHNldS5xKSA8LSAncHJlZGljdGVkLmlkJwojIGFkZCBuZXcgZGF0YXNsb3QgZm9yIE1CTyBwcmVkaWN0ZWQgSUQgdG8gbWFrZSB0aGUgbmV4dCBwcmVkaWN0aW9uCnNldS5xJEFJVzEyMC5wcmVkIDwtIElkZW50cyhzZXUucSkKRGltUGxvdChzZXUucSwgZ3JvdXAuYnkgPSAnQUlXMTIwLnByZWQnLCBsYWJlbCA9IFRSVUUpCiAKIyMgY2hlY2sgdGhlIHByb3BvcnRpb24gb2YgY2VsbCB0eXBlcyBwcmVkaWN0ZWQgaW4gZWFjaCBjbHVzdGVyCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC40LCBzZXUucSRNQk9BSVcucHJlZCkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCiMgdHJ5IGJhciBjaGFydApnZ3Bsb3QodC5sYWJsZXMsIGFlcyh5ID0gRnJlcSwgeCA9IFZhcjEsIGZpbGwgPSBWYXIyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ICJpZGVudGl0eSIpCgojIHNlZSBob3cgYWNjdXJhdGUgdGhlIHByZWRpY3Rpb25zIGFyZQpzZXUucSRwcmVkaWN0ZWQuaWQgPC0gaWZlbHNlKHNldS5xJHByZWRpY3Rpb24uc2NvcmUubWF4ID4gMC45NSwgc2V1LnEkcHJlZGljdGVkLmlkLCAiTm9uZSIpCgpJZGVudHMoc2V1LnEpIDwtICdwcmVkaWN0ZWQuaWQnCnNldS5xJEFJVzEyMC50aHJlc2ggPC0gSWRlbnRzKHNldS5xKQpEaW1QbG90KHNldS5xLCBncm91cC5ieSA9ICdBSVcxMjAudGhyZXNoJywgbGFiZWwgPSBUUlVFKQp0YWJsZShzZXUucSRBSVcxMjAucHJlZCkKdGFibGUoc2V1LnEkQUlXMTIwLnRocmVzaCkKCiMgdGhlIHByZWRpY3RlZCBjZWxsIHR5cGVzIG1ha2UgbW9yZSBzZW5zZSBmcm9tIHRoZSBBSVcwMDIgb3JnYW5vaWQKIyBub3cgcHJlZGljdCB3aXRoIHRoZSBBSVcwMDIgNjAgZGF5cyBvcmdhbm9pZAoKSWRlbnRzKEFJVzYwKSA8LSAiY2x1c3Rlci5pZHMiCkRlZmF1bHRBc3NheShBSVc2MCkgPC0gIlJOQSIKCmFuY2hvcnMgPC0gRmluZFRyYW5zZmVyQW5jaG9ycyhyZWZlcmVuY2UgPSBBSVc2MCwgcXVlcnkgPSBzZXUucSwgZGltcyA9IDE6MjUpCnByaW50KCJnZXR0aW5nIHByZWRpY3Rpb25zIikKcHJlZGljdGlvbnMgPC0gVHJhbnNmZXJEYXRhKGFuY2hvcnNldCA9IGFuY2hvcnMsIHJlZmRhdGEgPSBBSVc2MCRjbHVzdGVyLmlkcykgCnNldS5xIDwtIEFkZE1ldGFEYXRhKHNldS5xLCBtZXRhZGF0YSA9IHByZWRpY3Rpb25zKQpwcmludCh0YWJsZShzZXUucSRwcmVkaWN0ZWQuaWQpKQoKSWRlbnRzKHNldS5xKSA8LSAncHJlZGljdGVkLmlkJwojIGFkZCBuZXcgZGF0YXNsb3QgZm9yIE1CTyBwcmVkaWN0ZWQgSUQgdG8gbWFrZSB0aGUgbmV4dCBwcmVkaWN0aW9uCnNldS5xJEFJVzYwLnByZWQgPC0gSWRlbnRzKHNldS5xKQpEaW1QbG90KHNldS5xLCBncm91cC5ieSA9ICdBSVc2MC5wcmVkJywgbGFiZWwgPSBUUlVFKQogCiMjIGNoZWNrIHRoZSBwcm9wb3J0aW9uIG9mIGNlbGwgdHlwZXMgcHJlZGljdGVkIGluIGVhY2ggY2x1c3Rlcgp0LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuNCwgc2V1LnEkQUlXNjAucHJlZCkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCgojIHRyeSBiYXIgY2hhcnQKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKQoKIyBzZWUgaG93IGFjY3VyYXRlIHRoZSBwcmVkaWN0aW9ucyBhcmUKc2V1LnEkcHJlZGljdGVkLmlkIDwtIGlmZWxzZShzZXUucSRwcmVkaWN0aW9uLnNjb3JlLm1heCA+IDAuOTUsIHNldS5xJHByZWRpY3RlZC5pZCwgIk5vbmUiKQoKSWRlbnRzKHNldS5xKSA8LSAncHJlZGljdGVkLmlkJwpzZXUucSRBSVc2MC50aHJlc2ggPC0gSWRlbnRzKHNldS5xKQpEaW1QbG90KHNldS5xLCBncm91cC5ieSA9ICdBSVc2MC50aHJlc2gnLCBsYWJlbCA9IFRSVUUpCnRhYmxlKHNldS5xJEFJVzYwLnByZWQpCnRhYmxlKHNldS5xJEFJVzYwLnRocmVzaCkKCgoKIyBtb3N0IG9mIHRoZSBjZWxscyBhcmUgcHJlZGljdGVkIGFzIE5QQ3MgaW4gbWFueSBwb3B1bGF0aW9ucwoKCgpgYGAKCmBgYHtyfQojIHNhdmUgd2l0aCBwcmVkaWN0aW9ucyBzbyBmYXIKI3NhdmVSRFMoc2V1LnEsICIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9QaGVub0lEL3NjUk5Bc2VxU29ydGVkL29ianMvR2xpYTJMYWJsZWRTZXUwMzEwMjAyMi5SRFMiKQoKc2V1LnEgPC0gcmVhZFJEUygiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvUGhlbm9JRC9zY1JOQXNlcVNvcnRlZC9vYmpzL0dsaWEyTGFibGVkU2V1MDMxMDIwMjIuUkRTIikKCgpgYGAKCgpTZWUgaG93IG1hbnkgY2VsbHMgYXJlIHByZWRpY3RlZCBhcyBhc3Ryb2N5dGVzIHdpdGggdGhlIHRocmVzaG9sZAoKYGBge3J9CgpEQXN1YnR5cGVzIDwtIHJlYWRSRFMoIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL01hY29za29fRGF0YS9EQXN1Ymdyb3Vwc19wcm9jZXNzZWQuUmRzIikKCklkZW50cyhhc3Ryby5yZWYpIDwtICJDZWxsX1N1YnR5cGUiCkRlZmF1bHRBc3NheShhc3Ryby5yZWYpIDwtICJSTkEiCgojIGZpbmQgdGhlIHJlZmVyZW5jZSBhbmNob3JzCnByaW50KCJmaW5kaW5nIHJlZmVyZW5jZSBhbmNob3JzIikKYW5jaG9ycyA8LSBGaW5kVHJhbnNmZXJBbmNob3JzKHJlZmVyZW5jZSA9IERBc3VidHlwZXMgLHF1ZXJ5ID0gc2V1LnEsIGRpbXMgPSAxOjIwKQpwcmludCgiZ2V0dGluZyBwcmVkaWN0aW9ucyIpCnByZWRpY3Rpb25zIDwtIFRyYW5zZmVyRGF0YShhbmNob3JzZXQgPSBhbmNob3JzLCByZWZkYXRhID0gYXN0cm8ucmVmJENlbGxfU3VidHlwZSwgay53ZWlnaHQgPSAxMCkKc2V1LnEgPC0gQWRkTWV0YURhdGEoc2V1LnEsIG1ldGFkYXRhID0gcHJlZGljdGlvbnMpCnByaW50KHRhYmxlKHNldS5xJHByZWRpY3RlZC5pZCkpCgpJZGVudHMoc2V1LnEpIDwtICdwcmVkaWN0ZWQuaWQnCiMgYWRkIG5ldyBkYXRhc2xvdCBmb3IgTUJPIHByZWRpY3RlZCBJRCB0byBtYWtlIHRoZSBuZXh0IHByZWRpY3Rpb24Kc2V1LnEkYXN0cm8ucHJlZCA8LSBJZGVudHMoc2V1LnEpCkRpbVBsb3Qoc2V1LnEsIGdyb3VwLmJ5ID0gJ2FzdHJvLnByZWQnLCBsYWJlbCA9IFRSVUUpCnRhYmxlKHNldS5xJGFzdHJvLnByZWQpCgpzZXUucSRwcmVkaWN0ZWQuaWQgPC0gaWZlbHNlKHNldS5xJHByZWRpY3Rpb24uc2NvcmUubWF4ID4gMC45NSwgc2V1LnEkcHJlZGljdGVkLmlkLCAibm9uZSIpCnByaW50KHRhYmxlKHNldS5xJHByZWRpY3RlZC5pZCkpCgpJZGVudHMoc2V1LnEpIDwtICdwcmVkaWN0ZWQuaWQnCnNldS5xJGFzdHJvLnByZWQudGhyZXNoIDwtIElkZW50cyhzZXUucSkKRGltUGxvdChzZXUucSwgZ3JvdXAuYnkgPSAnYXN0cm8ucHJlZC50aHJlc2gnLCBsYWJlbCA9IFRSVUUpCnRhYmxlKHNldS5xJGFzdHJvLnByZWQudGhyZXNoKQoKCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRhc3Ryby5wcmVkLnRocmVzaCkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCmdncGxvdCh0LmxhYmxlcywgYWVzKHkgPSBGcmVxLCB4ID0gVmFyMSwgZmlsbCA9IFZhcjIpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdD0gImlkZW50aXR5IikgKyBSb3RhdGVkQXhpcygpIAp0b3AucHJlZC5hc3RybyA8LSBhcy5kYXRhLmZyYW1lKHQubGFibGVzICAlPiUgZ3JvdXBfYnkoVmFyMSkgICU+JSB0b3BfbigyLCBGcmVxKSkKZGYudG9wLmFzdHJvIDwtIHRvcC5wcmVkLmFzdHJvW29yZGVyKHRvcC5wcmVkLmFzdHJvJFZhcjEsLXRvcC5wcmVkLmFzdHJvJEZyZXEpLF0Kcm93Lm5hbWVzKGRmLnRvcC5hc3RybykgPC0gTlVMTAoKCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRhc3Ryby5wcmVkKSkKdC5sYWJsZXMkRnJlcSA8LSBhcy5kb3VibGUodC5sYWJsZXMkRnJlcSkKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKSArIFJvdGF0ZWRBeGlzKCkgCnRvcC5wcmVkLmFzdHJvIDwtIGFzLmRhdGEuZnJhbWUodC5sYWJsZXMgICU+JSBncm91cF9ieShWYXIxKSAgJT4lIHRvcF9uKDIsIEZyZXEpKQpkZi50b3AuYXN0cm8gPC0gdG9wLnByZWQuYXN0cm9bb3JkZXIodG9wLnByZWQuYXN0cm8kVmFyMSwtdG9wLnByZWQuYXN0cm8kRnJlcSksXQpyb3cubmFtZXMoZGYudG9wLmFzdHJvKSA8LSBOVUxMCgojIGEgbG90IG9mIHRoZXNlIGNlbGxzIGFyZSBhbHNvIGdldHRpbmcgbGFiZWxsZWQgYXMgYXN0cm9jeXRlcwoKCmBgYAoKRG8gdGhlc2UgZ2V0IGxhYmVsbGVkIGFzIERBIG5ldXJvbnMgdG9vPz8/CgpgYGB7cn0Kc2V1LnEgPC0gcmVhZFJEUygiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvUGhlbm9JRC9zY1JOQXNlcVNvcnRlZC9vYmpzL0dsaWEyTGFibGVkU2V1MDMxMDIwMjIuUkRTIikKCmBgYAoKCgpgYGB7cn0KCkRBc3VidHlwZXMgPC0gcmVhZFJEUygiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvTWFjb3Nrb19EYXRhL0RBc3ViZ3JvdXBzX3Byb2Nlc3NlZC5SZHMiKQpJZGVudHMoREFzdWJ0eXBlcykgPC0gIkNlbGxfU3VidHlwZSIKZGEucmVmIDwtIHN1YnNldChEQXN1YnR5cGVzLCBkb3duc2FtcGxlID0gNTAwKQoKIyBmaW5kIHRoZSByZWZlcmVuY2UgYW5jaG9ycwpwcmludCgiZmluZGluZyByZWZlcmVuY2UgYW5jaG9ycyIpCmFuY2hvcnMgPC0gRmluZFRyYW5zZmVyQW5jaG9ycyhyZWZlcmVuY2UgPSBkYS5yZWYsIHF1ZXJ5ID0gc2V1LnEsIGRpbXMgPSAxOjIwKQpwcmludCgiZ2V0dGluZyBwcmVkaWN0aW9ucyIpCnByZWRpY3Rpb25zIDwtIFRyYW5zZmVyRGF0YShhbmNob3JzZXQgPSBhbmNob3JzLCByZWZkYXRhID0gZGEucmVmJENlbGxfU3VidHlwZSwgay53ZWlnaHQgPSAxMCkKc2V1LnEgPC0gQWRkTWV0YURhdGEoc2V1LnEsIG1ldGFkYXRhID0gcHJlZGljdGlvbnMpCnByaW50KHRhYmxlKHNldS5xJHByZWRpY3RlZC5pZCkpCgpJZGVudHMoc2V1LnEpIDwtICdwcmVkaWN0ZWQuaWQnCiMgYWRkIG5ldyBkYXRhc2xvdCBmb3IgTUJPIHByZWRpY3RlZCBJRCB0byBtYWtlIHRoZSBuZXh0IHByZWRpY3Rpb24Kc2V1LnEkZGEucHJlZCA8LSBJZGVudHMoc2V1LnEpCkRpbVBsb3Qoc2V1LnEsIGdyb3VwLmJ5ID0gJ2RhLnByZWQnLCBsYWJlbCA9IFRSVUUpCnRhYmxlKHNldS5xJGRhLnByZWQpCgpzZXUucSRwcmVkaWN0ZWQuaWQgPC0gaWZlbHNlKHNldS5xJHByZWRpY3Rpb24uc2NvcmUubWF4ID4gMC45NSwgc2V1LnEkcHJlZGljdGVkLmlkLCAibm9uZSIpCgpJZGVudHMoc2V1LnEpIDwtICdwcmVkaWN0ZWQuaWQnCnNldS5xJGRhLnByZWQudGhyZXNoIDwtIElkZW50cyhzZXUucSkKRGltUGxvdChzZXUucSwgZ3JvdXAuYnkgPSAnZGEucHJlZC50aHJlc2gnLCBsYWJlbCA9IFRSVUUpCnRhYmxlKHNldS5xJGRhLnByZWQudGhyZXNoKQoKCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRkYS5wcmVkLnRocmVzaCkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCmdncGxvdCh0LmxhYmxlcywgYWVzKHkgPSBGcmVxLCB4ID0gVmFyMSwgZmlsbCA9IFZhcjIpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdD0gImlkZW50aXR5IikgKyBSb3RhdGVkQXhpcygpIAp0b3AucHJlZC5hc3RybyA8LSBhcy5kYXRhLmZyYW1lKHQubGFibGVzICAlPiUgZ3JvdXBfYnkoVmFyMSkgICU+JSB0b3BfbigyLCBGcmVxKSkKZGYudG9wLmFzdHJvIDwtIHRvcC5wcmVkLmFzdHJvW29yZGVyKHRvcC5wcmVkLmFzdHJvJFZhcjEsLXRvcC5wcmVkLmRhJEZyZXEpLF0Kcm93Lm5hbWVzKGRmLnRvcC5hc3RybykgPC0gTlVMTAoKCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRhc3Ryby5wcmVkKSkKdC5sYWJsZXMkRnJlcSA8LSBhcy5kb3VibGUodC5sYWJsZXMkRnJlcSkKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKSArIFJvdGF0ZWRBeGlzKCkgCnRvcC5wcmVkLmFzdHJvIDwtIGFzLmRhdGEuZnJhbWUodC5sYWJsZXMgICU+JSBncm91cF9ieShWYXIxKSAgJT4lIHRvcF9uKDIsIEZyZXEpKQpkZi50b3AuYXN0cm8gPC0gdG9wLnByZWQuYXN0cm9bb3JkZXIodG9wLnByZWQuYXN0cm8kVmFyMSwtdG9wLnByZWQuYXN0cm8kRnJlcSksXQpyb3cubmFtZXMoZGYudG9wLmFzdHJvKSA8LSBOVUxMCgoKIyBhZnRlciB0aHJlc2hvbGRpbmcgdmVyeSBmZXcgY2VsbHMgYXJlIHByZWRpY3RlZCBhcyBuZXVyb25zCgoKCmBgYAoKQ29tcGFyZSBwcmVkaWN0aW9ucyAtIG1ha2UgYSBwcmVkaWN0aW9ucyB0YWJsZQoKYGBge3J9CgojIEFJVzAwMiAxMjAgZGF5cyBwcmVkaWN0aW9ucyAtIHRha2UgdGhlIHRocmVzaG9sZGVkIG9wdGlvbnMKdC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShzZXUucSRSTkFfc25uX3Jlcy4wLjIsIHNldS5xJEFJVzEyMC50aHJlc2gpKQp0LmxhYmxlcyRGcmVxIDwtIGFzLmRvdWJsZSh0LmxhYmxlcyRGcmVxKQpnZ3Bsb3QodC5sYWJsZXMsIGFlcyh5ID0gRnJlcSwgeCA9IFZhcjEsIGZpbGwgPSBWYXIyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ICJpZGVudGl0eSIpICsgUm90YXRlZEF4aXMoKSAKdG9wLnByZWQuY2VsbHR5cGUuQUlXMTIwIDwtIGFzLmRhdGEuZnJhbWUodC5sYWJsZXMgICU+JSBncm91cF9ieShWYXIxKSAgJT4lIHRvcF9uKDIsIEZyZXEpKQpkZi50b3AuYWl3MTIwIDwtIHRvcC5wcmVkLmNlbGx0eXBlLkFJVzEyMFtvcmRlcih0b3AucHJlZC5jZWxsdHlwZS5BSVcxMjAkVmFyMSwtdG9wLnByZWQuY2VsbHR5cGUuQUlXMTIwJEZyZXEpLF0Kcm93Lm5hbWVzKGRmLnRvcC5haXcxMjApIDwtIE5VTEwKZGYudG9wLmFpdzEyMCRJIDwtIHJvdy5uYW1lcyhkZi50b3AuYWl3MTIwKQoKIyBBSVcwMDIgNjAgZGF5cyBwcmVkaWN0aW9ucwp0LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuMiwgc2V1LnEkQUlXNjAudGhyZXNoKSkKdC5sYWJsZXMkRnJlcSA8LSBhcy5kb3VibGUodC5sYWJsZXMkRnJlcSkKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKSArIFJvdGF0ZWRBeGlzKCkgCnRvcC5wcmVkLmNlbGx0eXBlLkFJVzYwIDwtYXMuZGF0YS5mcmFtZSh0LmxhYmxlcyAgJT4lIGdyb3VwX2J5KFZhcjEpICAlPiUgdG9wX24oMiwgRnJlcSkpCmRmLnRvcC5haXc2MCA8LSB0b3AucHJlZC5jZWxsdHlwZS5BSVc2MFtvcmRlcih0b3AucHJlZC5jZWxsdHlwZS5BSVc2MCRWYXIxLC10b3AucHJlZC5jZWxsdHlwZS5BSVc2MCRGcmVxKSxdCnJvdy5uYW1lcyhkZi50b3AuYWl3NjApIDwtIE5VTEwKZGYudG9wLmFpdzYwJEkgPC0gcm93Lm5hbWVzKGRmLnRvcC5haXc2MCkKCgojIEFTVDIzIDE2NSBkYXlzIHByZWRpY3Rpb25zCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRNQk9BU1QyMy50aHJlc2gpKQp0LmxhYmxlcyRGcmVxIDwtIGFzLmRvdWJsZSh0LmxhYmxlcyRGcmVxKQpnZ3Bsb3QodC5sYWJsZXMsIGFlcyh5ID0gRnJlcSwgeCA9IFZhcjEsIGZpbGwgPSBWYXIyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ICJpZGVudGl0eSIpICsgUm90YXRlZEF4aXMoKSAKdG9wLnByZWQuY2VsbHR5cGUuQVNUMjMgPC0gYXMuZGF0YS5mcmFtZSh0LmxhYmxlcyAgJT4lIGdyb3VwX2J5KFZhcjEpICAlPiUgdG9wX24oMiwgRnJlcSkpCmRmLnRvcC5BU1QyMyA8LSB0b3AucHJlZC5jZWxsdHlwZS5BU1QyM1tvcmRlcih0b3AucHJlZC5jZWxsdHlwZS5BU1QyMyRWYXIxLC10b3AucHJlZC5jZWxsdHlwZS5BU1QyMyRGcmVxKSxdCnJvdy5uYW1lcyhkZi50b3AuQVNUMjMpIDwtIE5VTEwKZGYudG9wLkFTVDIzJEkgPC0gcm93Lm5hbWVzKGRmLnRvcC5BU1QyMykKCiMgYWRkIHRoZSB0aHJlc2hvbGQgQXN0cm8gcHJlZGljdGlvbnMgCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRhc3Ryby5wcmVkLnRocmVzaCkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCmdncGxvdCh0LmxhYmxlcywgYWVzKHkgPSBGcmVxLCB4ID0gVmFyMSwgZmlsbCA9IFZhcjIpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdD0gImlkZW50aXR5IikgKyBSb3RhdGVkQXhpcygpIAp0b3AucHJlZC5jZWxsdHlwZS5hc3RybyA8LSBhcy5kYXRhLmZyYW1lKHQubGFibGVzICAlPiUgZ3JvdXBfYnkoVmFyMSkgICU+JSB0b3BfbigyLCBGcmVxKSkKZGYudG9wLmFzdHJvIDwtIHRvcC5wcmVkLmNlbGx0eXBlLmFzdHJvW29yZGVyKHRvcC5wcmVkLmNlbGx0eXBlLmFzdHJvJFZhcjEsLXRvcC5wcmVkLmNlbGx0eXBlLmFzdHJvJEZyZXEpLF0Kcm93Lm5hbWVzKGRmLnRvcC5hc3RybykgPC0gTlVMTApkZi50b3AuYXN0cm8kSSA8LSByb3cubmFtZXMoZGYudG9wLmFzdHJvKQoKIyBhZGQgdGhlIG5ldXJvbnMgcHJlZGljdGlvbnMgCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRkYS5wcmVkLnRocmVzaCkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCmdncGxvdCh0LmxhYmxlcywgYWVzKHkgPSBGcmVxLCB4ID0gVmFyMSwgZmlsbCA9IFZhcjIpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdD0gImlkZW50aXR5IikgKyBSb3RhdGVkQXhpcygpIAp0b3AucHJlZC5jZWxsdHlwZS5kYSA8LSBhcy5kYXRhLmZyYW1lKHQubGFibGVzICAlPiUgZ3JvdXBfYnkoVmFyMSkgICU+JSB0b3BfbigyLCBGcmVxKSkKZGYudG9wLmRhIDwtIHRvcC5wcmVkLmNlbGx0eXBlLmRhW29yZGVyKHRvcC5wcmVkLmNlbGx0eXBlLmRhJFZhcjEsLXRvcC5wcmVkLmNlbGx0eXBlLmRhJEZyZXEpLF0Kcm93Lm5hbWVzKGRmLnRvcC5kYSkgPC0gTlVMTApkZi50b3AuZGEkSSA8LSByb3cubmFtZXMoZGYudG9wLmRhKQoKcHJlZC50YWJsZSA8LSBtZXJnZShkZi50b3AuQVNUMjMsIGRmLnRvcC5haXc2MCwgYnkgPSAnSScsIGFsbCA9IFRSVUUpCnByZWQudGFibGUgPC0gbWVyZ2UocHJlZC50YWJsZSwgZGYudG9wLmFpdzEyMCwgYnkgPSAnSScpCnByZWQudGFibGUgPC0gbWVyZ2UocHJlZC50YWJsZSwgZGYudG9wLmFzdHJvLCBieSA9ICdJJykKcHJlZC50YWJsZSA8LSBtZXJnZShwcmVkLnRhYmxlLCBkZi50b3AuZGEsIGJ5ID0gJ0knKQoKcHJlZC50YWJsZQoKCmBgYAoKUHJlZGljdGVkIGNsdXN0ZXIgYW5ub3RhdGlvbnMKMAlVbmtub3duLyBOUEMKMQlSRwoyCWFzdHJvCjMJUkcKNAluZXVyb25zCjUJUkcKCkxvb2sgYXQgZ2VuZSBsaXN0cyB3aXRoIGtub3duIG1hcmtlcnMKCmBgYHtyfQoKSWRlbnRzKHNldS5xKSA8LSAnUk5BX3Nubl9yZXMuMC4yJwoKIyBtYW55IGNlbGwgdHlwZXMgbGlzdApmZWF0dXJlX2xpc3QgPSBjKCJNS0k2NyIsIlNPWDIiLCJQT1U1RjEiLCJETFgyIiwiUEFYNiIsIlNPWDkiLCJIRVMxIiwiTkVTIiwiUkJGT1gzIiwiTUFQMiIsIk5DQU0xIiwiQ0QyNCIsIkdSSUEyIiwiR1JJTjJCIiwiR0FCQlIxIiwiR0FEMSIsIkdBRDIiLCJHQUJSQTEiLCJHQUJSQjIiLCJUSCIsIkFMREgxQTEiLCJMTVgxQiIsIk5SNEEyIiwiQ09SSU4iLCJDQUxCMSIsIktDTko2IiwiQ1hDUjQiLCJJVEdBNiIsIlNMQzFBMyIsIkNENDQiLCJBUVA0IiwiUzEwMEIiLCAiUERHRlJBIiwiT0xJRzIiLCJNQlAiLCJDTEROMTEiLCJWSU0iLCJWQ0FNMSIpCgpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gZmVhdHVyZV9saXN0LCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIpCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gZmVhdHVyZV9saXN0KSArUm90YXRlZEF4aXMoKQoKIyBEb3BhbWluZXJnaWMgbWFya2VycwpQRF9wb3VsaW4gPSBjKCJUSCIsIlNMQzZBMyIsIlNMQzE4QTIiLCJTT1g2IiwiTkRORiIsIlNOQ0ciLCJBTERIMUExIiwiQ0FMQjEiLCJUQUNSMiIsIlNMQzE3QTYiLCJTTEMzMkExIiwiT1RYMiIsIkdSUCIsIkxQTCIsIkNDSyIsIlZJUCIpCgpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gUERfcG91bGluLCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIpCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gUERfcG91bGluKStSb3RhdGVkQXhpcygpCgplYWxyeU5ldXIgPSBjKCJEQ1giLCJORVVST0QxIiwiVEJSMSIpCnByb2xpZmVyYXRpb24gPSBjKCJQQ05BIiwiTUtJNjciKQpuZXVyYWxzdGVtID0gYygiU09YMiIsIk5FUyIsIlBBWDYiLCJNQVNIMSIpCgpmZWF0dXJlX2xpc3QgPC0gYygiRENYIiwiTkVVUk9EMSIsIlRCUjEiLCJQQ05BIiwiTUtJNjciLCJTT1gyIiwiTkVTIiwiUEFYNiIsIk1BU0gxIikKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IGZlYXR1cmVfbGlzdCwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IGZlYXR1cmVfbGlzdCkrUm90YXRlZEF4aXMoKQoKCm1hdF9uZXVyb24gPSBjKCJSQkZPWDMiLCJTWVAiLCJETEc0NSIsIlZBTVAxIiwiVkFNUDIiLCJUVUJCMyIsIlNZVDEiLCJCU04iLCJIT01FUjEiLCJTTEMxN0E2IikgCiMgTmV1TiBpcyBGT1gzIC0gUkJGT1gzCiMgUFNEOTUgYWxzbyBTUC05MCBvciBETEc0CiMgVkdMVVQyIGlzIFNMQzE3QTYKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IG1hdF9uZXVyb24sIHNpemU9MywgYW5nbGUgPTkwLCBncm91cC5iYXIuaGVpZ2h0ID0gMC4wMikKIyBjbHVzdGVyIDQgYWxzbyBzaG93IG1hdHVyZSBuZXVyb24gbWFya2VycwpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IG1hdF9uZXVyb24pK1JvdGF0ZWRBeGlzKCkKIyBleGNpdGF0b3J5IG5ldXJvbiBtYXJrZXJzCmV4ID0gYygiR1JJQTIiLCJHUklBMSIsIkdSSUE0IiwiR1JJTjEiLCJHUklOMkIiLCJHUklOMkEiLCJHUklOM0EiLCJHUklOMyIsIkdSSVAxIiwiQ0FNSzJBIikKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IGV4LCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIpCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gZXgpK1JvdGF0ZWRBeGlzKCkKIyBpbmhpYml0b3J5IG5ldXJvbiBtYXJrZXJzCmluaCA9IGMoIkdBRDEiLCJHQUQyIiwgIkdBVDEiLCJQVkFMQiIsIkdBQlIyIiwiR0FCUjEiLCJHQlJSMSIsIkdBQlJCMiIsIkdBQlJCMSIsIkdBQlJCMyIsIkdBQlJBNiIsIkdBQlJBMSIsIkdBQlJBNCIsIlRSQUsyIikKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IGluaCwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IGluaCkrUm90YXRlZEF4aXMoKQojIGNsdXN0ZXIgNCBpcyBtb3JlIGV4Y2l0YXRvcnkgdGhhbiBpbmhiaXRvcnkgYnV0IG5laXRoZXIgbWFya2VyIHNldCBoYXMgbXVjaCBleHByZXNzaW9uIAoKIyMjIGdsaWEgbWFya2VycwptaWNyb2dsaWEgPSBjKCJQVFBSQyIsIkFJRjEiLCJBREdSRTEiKSAgIyBBREdSRTEgaXMgYSBtaWNyb2dsaWEgbWFya2VyIEY0LzgwLCBDRDQ1IGlzIFBUUFJDLCBnZW5lIG5hbWUgSUJBMSBpcyBBSUYxCmFzdG9sZ05QQ3Byb21pY3JvID0gYygiR0ZBUCIsIlMxMDBCIiwiU0xDMUEyIiwiTUJQIiwiU09YMTAiLCJTUFAxIiwiRENYIiwiTkVVUk9EMSIsIlRCUjEiLCJQQ05BIiwiTUtJNjciLCJQVFBSQyIsIkFJRjEiLCJBREdSRTEiKQojIG5vdGUgR0xUMSBpcyBFQUFUMiB3aGljaCBpcyBTTEMxQTIgZ2x1dGF0bWF0ZSB0cmFuc3BvcnRlcgojIGVwaXRoZWxpYWwKZXBpID0gYygiSEVTMSIsIkhFUzUiLCJTT1gyIiwiU09YMTAiLCJORVMiLCJDREgxIiwiTk9UQ0gxIikgIyBlLWNhZGhlcmluIGlzIENESDEKCkRvSGVhdG1hcChzZXUucSwgZmVhdHVyZXMgPSBhc3RvbGdOUENwcm9taWNybywgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IGFzdG9sZ05QQ3Byb21pY3JvKStSb3RhdGVkQXhpcygpCiMgY2x1c3RlciA0IGlzIG1vcmUgZXhjaXRhdG9yeSB0aGFuIGluaGJpdG9yeSBidXQgbmVpdGhlciBtYXJrZXIgc2V0IGhhcyBtdWNoIGV4cHJlc3Npb24gCkRvSGVhdG1hcChzZXUucSwgZmVhdHVyZXMgPSBlcGksIHNpemU9MywgYW5nbGUgPTkwLCBncm91cC5iYXIuaGVpZ2h0ID0gMC4wMikKRG90UGxvdChzZXUucSwgZmVhdHVyZXMgPSBlcGkpK1JvdGF0ZWRBeGlzKCkKCiMgYWxzbyBhZGQgUmFkaWFsIGdsaWEgbWFya2VyIG92ZXJsYXAgd2l0aCBHbGlhIGFuZCBOZXVyb25zCgpmZWF0dXJlcyA8LSBjKCJQVFBSQyIsIkFJRjEiLCJBREdSRTEiLCAiVklNIiwgIlROQyIsIlBUUFJaMSIsIkZBTTEwN0EiLCJIT1BYIiwiTElGUiIsCiAgICAgICAgICAgICAgIklUR0I1IiwiSUw2U1QiKQpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gZmVhdHVyZXMsIHNpemU9MywgYW5nbGUgPTkwLCBncm91cC5iYXIuaGVpZ2h0ID0gMC4wMikKRG90UGxvdChzZXUucSwgZmVhdHVyZXMgPSBmZWF0dXJlcykrUm90YXRlZEF4aXMoKQoKIyByYWRpYWwgZ2xpYSBtYXJrZXJzCnJnIDwtIGMoIlZJTSIsIk5FUyIsIlBBWDYiLCJIRVMxIiwiRUFBVDEiLCJOQ0FEMSIsIlNPWDIiLCJGQUJQNyIpCkRvSGVhdG1hcChzZXUucSwgZmVhdHVyZXMgPSByZywgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IHJnKStSb3RhdGVkQXhpcygpCgojIE5QQyBhbmQgcmFkaWFsIGdsaWEgYXJlIHZlcnkgc2ltaWxhcgoKYGBgCk1hcmtlciBleHByZXNzaW9uIHByZWRpY3Rpb25zCkNsdXN0ZXIgMCAtIHVua25vd24KQ2x1c3RlciAxIC0gUkcKQ2x1c3RlciAyIC0gdW5rbm93bgpDbHVzdGVyIDMgLSBSRwpjbHVzdGVyIDQgLSBpbW1hdHVyZSBuZXVyb25zCkNsdXN0ZXIgNSAtIFJHLCBvcGMKCgpDaGVjayB0aGUgbGV2ZWxzIG9mIFJOQSBpbiBlYWNoIGNsdXN0ZXIgCgpgYGB7cn0KVmxuUGxvdChzZXUucSwgZmVhdHVyZXMgPSAibkZlYXR1cmVfUk5BIikKCmBgYApDbHVzdGVyIDAgYW5kIDIgaGF2ZSBmZXdlciBzZXF1ZW5jZXMgdGhhbiBvdGhlciBncm91cHMgYW5kIHRodXMgbm8gbWFya2VycwpQb3NzaWJseSByZW1vdmUgdGhlc2UgaXMgdGhleSBkb24ndCBjb21lIHVwIHdpdGggc29tZSBtYXJrZXJzCgpGaW5kIGNsdXN0ZXIgbWFya2VycwoKYGBge3J9CklkZW50cyhzZXUucSkgPC0gJ1JOQV9zbm5fcmVzLjAuMicKQ2x1c3Rlck1hcmtlcnMgPC0gRmluZEFsbE1hcmtlcnMoc2V1LnEsIG9ubHkucG9zID0gVFJVRSkKCnRvcDUgPC0gQ2x1c3Rlck1hcmtlcnMgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3BfbihuPTUsIHd0ID0gYXZnX2xvZzJGQykKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IHRvcDUkZ2VuZSwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyKQoKI3dyaXRlLmNzdihDbHVzdGVyTWFya2VycywiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvUGhlbm9JRC9zY1JOQXNlcVNvcnRlZC9HbGlhMlJHQ2x1c3Rlck1hcmtlcnNfbmV3LmNzdiIpCgpJZGVudHMoc2V1LnEpIDwtICdSTkFfc25uX3Jlcy4wLjEnCkNsdXN0ZXJNYXJrZXJzIDwtIEZpbmRBbGxNYXJrZXJzKHNldS5xLCBvbmx5LnBvcyA9IFRSVUUpCgp0b3A1IDwtIENsdXN0ZXJNYXJrZXJzICU+JSBncm91cF9ieShjbHVzdGVyKSAlPiUgdG9wX24obj01LCB3dCA9IGF2Z19sb2cyRkMpCkRvSGVhdG1hcChzZXUucSwgZmVhdHVyZXMgPSB0b3A1JGdlbmUsIHNpemU9MywgYW5nbGUgPTkwLCBncm91cC5iYXIuaGVpZ2h0ID0gMC4wMikKCgpgYGAKTWFya2VycyBvZiAyIGFyZSBtYXRjaGluZyB3aXRoIDUgcG9zc2libHkgbWVyZ2UgdGhlc2UgdG9nZXRoZXIKQ2x1c3RlciAwIG1hcmtlcnMgZG9uJ3QgbG9vayB1cCByZWd1bGF0ZWQgYnV0IHRoZSBsaXN0IGlzIGxvbmcKCkxvb2sgYXQgdGhlIGxpYnJhcmllcwoKYGBge3J9CmxpYnJhcnkoZW5yaWNoUikKCnNldEVucmljaHJTaXRlKCJFbnJpY2hyIikgIyBIdW1hbiBnZW5lcwojIGxpc3Qgb2YgYWxsIHRoZSBkYXRhYmFzZXMKCiMgbGliYXJpZXMgd2l0aCBjZWxsIHR5cGVzCgpkYiA8LSBjKCdEZXNjYXJ0ZXNfQ2VsbF9UeXBlc19hbmRfVGlzc3VlXzIwMjEnLAogICAgICAgICdDZWxsTWFya2VyX0F1Z21lbnRlZF8yMDIxJywnQXppbXV0aF9DZWxsX1R5cGVzXzIwMjEnKQoKIyBlbnJpY2hyKGdlbmVzLCBkYXRhYmFzZXMgPSBOVUxMKQoKI0knbGwgcnVuIHRoZSBjbHVzdGVycyBvbmUgYXQgYSB0aW1lCgpOMS5jMCA8LSBDbHVzdGVyTWFya2VycyAlPiUgZmlsdGVyKGNsdXN0ZXIgPT0gMCAmIGF2Z19sb2cyRkMgPiAwKQpnZW5lcyA8LSBOMS5jMCRnZW5lCgpOMS5jMC5FciA8LSBlbnJpY2hyKGdlbmVzLCBkYXRhYmFzZXMgPSBkYikKcGxvdEVucmljaChOMS5jMC5FcltbMV1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jMC5FcltbMl1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jMC5FcltbM11dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKCgpOMS5Fci5nZW5lcy4xIDwtIE4xLmMwLkVyW1sxXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjEKCk4xLkVyLmdlbmVzLjIgPC0gTjEuYzAuRXJbWzJdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMgoKTjEuRXIuZ2VuZXMuMyA8LSBOMS5jMC5FcltbM11dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4zCgoKCgoKCmBgYAoKQWRkIHNvbWUgY2VsbCB0eXBlIGFubm90YXRpb25zCgpgYGB7cn0KCklkZW50cyhzZXUucSkgPC0gJ1JOQV9zbm5fcmVzLjAuMicKCmNsdXN0ZXIuaWRzIDwtIGMoIkdsaWExIiwiUkcxIiwiR2xpYTIiLCJSRzIiLCJOZXVyb25zSW1tYXR1cmUiLCJSRzMiKQoKbmFtZXMoY2x1c3Rlci5pZHMpIDwtIGxldmVscyhzZXUucSkKc2V1LnEgPC0gUmVuYW1lSWRlbnRzKHNldS5xLCBjbHVzdGVyLmlkcykKc2V1LnEkc3ViZ3JvdXBzIDwtIElkZW50cyhzZXUucSkKCiNEaW1QbG90KHNldS5xLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjInLCBsYWJlbCA9IFRSVUUpCkRpbVBsb3Qoc2V1LnEsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgbGFiZWwgPSBUUlVFLCBncm91cC5ieSA9ICdzdWJncm91cHMnLCByZXBlbCA9IFRSVUUpCgoKCmBgYAoKYGBge3J9CiMgc2F2ZSBmaWxlCnNhdmVSRFMoc2V1LnEsICIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9QaGVub0lEL3NjUk5Bc2VxU29ydGVkL29ianMvR2xpYTJMYWJsZWRTZXUwMzEwMjAyMi5SRFMiKQoKYGBgCgpNYWluIGNlbGwgZ3JvdXBzCgpgYGB7cn0KCklkZW50cyhzZXUucSkgPC0gJ1JOQV9zbm5fcmVzLjAuMicKCmNsdXN0ZXIuaWRzIDwtIGMoIlJHIiwiUkciLCJSRyIsIlJHIiwiTmV1cm9uc0ltbWF0dXJlIiwiUkciKQoKbmFtZXMoY2x1c3Rlci5pZHMpIDwtIGxldmVscyhzZXUucSkKc2V1LnEgPC0gUmVuYW1lSWRlbnRzKHNldS5xLCBjbHVzdGVyLmlkcykKc2V1LnEkQ2VsbF9UeXBlcyA8LSBJZGVudHMoc2V1LnEpCgojRGltUGxvdChzZXUucSwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC4yJywgbGFiZWwgPSBUUlVFKQpEaW1QbG90KHNldS5xLCByZWR1Y3Rpb24gPSAidW1hcCIsIGxhYmVsID0gVFJVRSwgZ3JvdXAuYnkgPSAnQ2VsbF9UeXBlcycsIHJlcGVsID0gVFJVRSkKCnNhdmVSRFMoc2V1LnEsICIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9QaGVub0lEL3NjUk5Bc2VxU29ydGVkL29ianMvR2xpYTJMYWJsZWRTZXUwMzEwMjAyMi5SRFMiKQoKYGBgCgpQcm9wb3J0aW9ucyBvZiBjZWxsIHR5cGVzCgpgYGB7cn0KCnRhYmxlKHNldS5xJENlbGxfVHlwZXMpCmRpbShzZXUucSkKCnBycCA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJENlbGxfVHlwZXMpKQpwcnAKCnBycCRwcm9wIDwtIHBycCRGcmVxL3N1bShwcnAkRnJlcSkqMTAwCnBycCRTYW1wbGUgPC0gJ1JhZGlhbEdsaWEnCnBycAoKCmBgYAoKSSdsbCBjYWxjdWxhdGUgdGhlIHByb3BvcnRpb25zIGZvciBlYWNoIGNlbGwgdHlwZSBhbmQgbWFrZSBhIHRhYmxlIG9yIHBsb3QgaW4gdGhlIGNvbXBhcmlzb24gd29ya2Jvb2suIAoKCgo=